Fork me on GitHub
#clara
<
2017-02-10
>
gamecubate03:02:18

@wparker I didn’t want to spend too much time digging into this. So, I’ve switched over to core.logic but I have to say progress is glacial (this said less than 2 hours after the switch). Clara’s eloquent DSL I miss already.

wparker15:02:37

To elaborate a bit, those are basically linter warnings that seem related to the rebinding, in a particular namespace, of core Clojure library definitions to new values. You can look at the source in both cases for whatever version of ClojureScript and Plumatic Schema you’re using to see those redefinitions happening. Whether that is good style in any particular case is a matter of opinion, but I don’t think the linter warnings are actually errors. Obviously your choice to use Clara in any project or not, but nothing I see here makes me think there is a bug with Clara’s ClojureScript support. That said, Clara’s ClojureScript certainly isn’t as hardened as the JVM version and bug reports are welcome.

gamecubate16:02:04

@wparker End of day when I wrote this. I wasn’t thinking. Of course they were warnings! I gave up there and then instead of doing what I normally do (which is to ignore warnings) and proceed. Will resume Clara tests. Thanks for the nudge. 🙂

gamecubate16:02:13

Macros… Checking Clara docs, I see mk-session is a macro indeed. I need to probably add a

(:require-macros [???])
directive. Will try...

ryanbrush16:02:30

Note that mk-session doesn't exist and isn't support in ClojureScript, since it dynamically compiles rules. You'll need to use defsession (which compiles them upfront), as seen in that example. In fact, starting with that example, running it, and experimenting with changes to it is probably a pretty good way to get started with the ClojureScript flow.

gamecubate16:02:13

@ryanbrush Thanks. Going through the example now.

ryanbrush16:02:01

@gamecubate Sure thing! If you find problems, please log bugs or let us know. Just to warn you, we've used only the Clojure version in production and therefore haven't deeply optimized the CLJS flow so you might run into more issues there. But bug reports, and especially help tuning or optimizing the CLJS flow against real workloads, would be welcome.

ryanbrush16:02:59

@gamecubate I think we're also behind on the version of ClojureScript we've tested against, so validating against newer versions is welcome as well.

gamecubate17:02:08

@ryanbrush Would you recommend I run my code against 0.13.0-RC4 (as per README.md) or, per your example, 0.13.0-RC7?

ryanbrush17:02:13

@gamecubate Probably doesn't matter for your needs, but the readme is just out of date. 0.13.0-RC7 will be good. (We're overdue in just releasing 0.13.0 itself, so expect that in a release soon.)

gamecubate17:02:58

Wow. This is one great example.

gamecubate17:02:27

Just need to replace dommy with (my chosen) Reagent code.

ryanbrush17:02:05

Yeah, we probably should update the example to use a more modern approach. 🙂

gamecubate17:02:01

It works nicely, though.

gamecubate17:02:46

fire-rules
successful. Am plugging in reactive (test) UI right now.

gamecubate17:02:50

My first instinct (as with all Reagent app data) would be to wrap the session in a (reagent) atom, but defsession being a macro and all, not sure this is even feasible, nor desirable, nor useful.

gamecubate18:02:56

Done. Works nicely. Will now try and compile with advanced-optimizations.

gamecubate18:02:26

Clara it is, then. 🙂

ryanbrush18:02:03

@gamecubate Glad it works! Note that defsession will create the initial, empty session as a static var, but that can be referenced and manipulated like any other Clojure data structure. I haven't thought a ton of good design patterns with Reagent...but just thinking of the session as any other complex, immutable structure is probably a good start.

ryanbrush18:02:14

@gamecubate if you do come up with good patterns for using this with Reagent and are interested in sharing examples of doing so, we could look at including them in the examples project (possibly replacing the dommy example that exists today).

gamecubate19:02:33

So far still exploring. What I have done thus far is for my event handlers (someone enters data in a field and clicks on add button -> triggers handler) to insert new session data:

(-> my-session (insert (->Customer “Alex”)) (fire-rules))
. Now am trying to figure out what to do for my reagent components to show the changes. Normally, without Clara, the event handler would simply update the atom that my components are watching. But now, with Clara, inserted data is held in the session and I need to find a way for my components to track that instead.

gamecubate19:02:07

Now, with rules, the handler changes to:

gamecubate19:02:56

My customer-list component should change as well, and that’s where I am not sure how to proceed to get session data I need.

ryanbrush19:02:05

Not a Reagent expert, but I think it should be possible to keep a Clara session in a Reagent atom, and swap it out every time you update facts or fire rules.

gamecubate19:02:54

How do I access records of a certain type, say ClientRepresentative?

gamecubate19:02:22

(def session-db (reagent/atom my-session))

gamecubate19:02:37

How does one write a query that retrieves all records of a certain type? Something like

(defquery get-clients “” [] [???])

gamecubate19:02:32

with that type defined as

(defrecord Client [name])
.

gamecubate19:02:52

I might need an example for using accumulators/all. That looks like the one I need.

gamecubate19:02:03

Oh I see. might be

[?client <- Client]

gamecubate20:02:25

Got it. Just need to set a rule that updates the (reagent atom) db whenever a new session insert takes place.

gamecubate21:02:41

So, this works. I am not sure however that this should be added to examples because it only serves to demonstrate that using Clara and Reagent together requires (in my solution at least) an extra level of indirection (view -> event handler -> clara insert -> reagent atom db update -> view …). The business logic that Clara offers a DSL for is too simple in this case. I’ll try and think of something more convoluted before submitting said example.

ryanbrush21:02:57

Cool, glad it's working. No rush in adding something to the examples...it's just nice to see a pattern that works with Reagent.

ryanbrush21:02:37

One thing to note: the session itself is immutable, so you'll probably want to keep it in atom itself and swap out when you make changes. The rules you have above will work because they are just appending state, but you're actually resetting back to an old session state every time.

ryanbrush22:02:28

There are probably other interesting variations on this. For instance, we could have reactions that fire on a swap of an atom containing the session, and those reactions would query the session and update other state. This could be a little closer to the purely "reactive" ideals of Reagent, rather than having rules that actively update state.

gamecubate22:02:00

I see. Changes needed then; will think about it to see where and how. Thanks! Gotta go pick up kid @ daycare (immutable task for me :). Cheers.