Fork me on GitHub

@kingoftheknoll: probably I'd just have a :current-message handler that returns data based on the information in :route


@martinklepsch: waaaay back in the beginning I did consider using a multimethod approach instead of registation approach. They are both ways of doing Parametric dispatch (and, just to be clear, dispatch here means function call, not the re-frame meaning of dispatch)


So the multimethod approach would have been more "static"


y, true, multimethods are very similar


As I remember it, I kinda favored the registration approah because it was potentially more flexible.


And, so it has turned out


The new subscriptions approach would not have been possible with multimethods


By "new subscriptions approach" I'm talking about this which is ALSO coming in v0.8.0


Y, Daniel already told me about it good stuff 👍


I'm very excited by this new approach. Worked out so nicely in the end. You know when it has come together well when you shake your head and wonder "why the hell didn't I realise this all along".


Odd feeling. At once you are both thrilled with the result, and embarrsed to not have thought of it sooner (so bloody obvious) 🙂


One issue I just realized with a spec as I pasted above: you cannot parameterize subscriptions with ad-hoc values, in practice I haven't used this a lot so that's probably why I didn't think a lot about it


Correction: above, when talking about the new subscriptions, I should have said "Go directly to": (I've now editted the above)


@mikethompson: what's the kind of situation where you pass query-v with more than just the subscription id?


(subscribe [:item 42])


That 42 is the id of the item you want to want to subscribe to


Or (`subscribe [:all-items :over (kg 32) ])`


Or are you talking about the mysterious 3rd parameter to subscribe?


Right but wouldn't you just use (subscribe [:items]) and then pass plain data down the tree?


When I think of subscriptions I often imagine a select


It is a way of obtaining some data from app-db, which I'm imagining to be more like a database


So instead of seeing: select x, y, z from items where colour = "see through" I see: (subscribe [:items "see through"])


Now, of course, many times you don't need parameters


Many, many times.


But in the general case, you do


And that's what comes after the query-id


I previously handled a similar situation by putting these queries into the app-db and having a :queried subscription but the subscription param approach is arguably more flexible


It gets interesting when the "query" has to source data from a remote location


Right, I remember the "subscribing to a database" page


(Sorry for delay, got a phone call) Yes, exactly. This is our current thinking:


@escherize: thanks for posting, that project looks sweet!


whats the proper way to query my "app-db"? i am using localstorage. On init, I am populating the values into app-db. at some point after init, I want to query the app-db to see if a specific data was populated before I make api calls. been using handlers and subs to interact with app-db till this point.. doesn't seem correct for this scenario.


@javazquez: we either do it in a handler or along the lines of depending on what is driving the query


Is it worth it to do clojure.spec on re-frame db?


@blance: some form of schema-checking on re-frame app-db is absolutely definitely worth it


@blance: though once your app-db gets to be a significant structure you will probably only want to take the performance hit during development


would you validate when you put data in? or when you get it out through subscribe?


i have a middleware which validates before changes are applied to the app-db... that way you are guaranteed your app-db state is always consistent


cool. thanks


oh and do you have any perference between spec/schema?


i haven't used spec yet, so i couldn't say - schema has been great, but spec may be even better


one thing to look at - with ES6 WeakMaps it should be possible to create a very efficient schema check which could be used in production... if spec has such a thing that would be a great reason to choose it over schema


assuming your deployment targets support WeakMaps etc


I'll definetly take a look


@mikethompson about effects, are you familiar with sagas? I'm just looking into them now for the redux app I'm writing. In redux their primary use is for asynchronous stuff (data loading flows, etc.,) but the idea is, as far as I can tell so far, more general than that. I am still just figuring them out, but they look interesting.

amashi21:07:01 has a pretty detailed explanation of them in redux terms, which are not too far off from re-frame as far as I can tell.


The redux implementation uses ES6 generators, but I'd guess (though I'll admit to enough ignorance here that I could be quite wrong) that something similar could be done with core.async.


@fasahi Yeah, there is some similarity there to what I'm doing, actually. I'm actually only using d3 for mouse handling, which is sort of overkill (but this is a strictly internal app for my client, so it's OK to bloat it a bit.) The reason I did that is that d3 just gives you back mouse co-ordinates already normalized to the viewbox of the svg. That's pretty lazy, but...


That said, I actually think d3 is a really nice match for React, and I'm planning on doing some much more complicated visualization stuff soon so I want to look a lot harder at how to integrate the two, preferably in Clojurescript. d3 is pretty stateful, but people have been doing some really interesting stuff in terms of getting it to work in a more Reactish way- there's a performance hit there, but I think for a lot of applications it's likely OK, and it makes d3 a lot easier as far as I can tell. d3 is powerful, but not always easy to reason about, especially if you are writing interface that affects it.


@mikethompson At first glance, this looks a lot like sagas, actually. I think the main point is: "Again, the old way causes a side-effect (Booo!) and the new way describes, declaratively, in data, the side-effects required (Yaaa!)."


It;s funny- I tend to write a lot less tests than many people do, but I actually think the emphasis on testability leads to better code, even when you don't write the tests.


Sagas are generally sold on the fact that they make writing tests a lot easier- instead of mocking things you just test that the descriptions are correct.


Haskel IO. Elm Sideeffects. Etc.


And, yes, i agree about your observation on testing.


You might not use it, but clean testability is a good sign.


coeffects is the new horizon in this space.


I think it's kind of funny that the emphasis on testing, which probably really started with Kent Beck, the epitome of an OO programmer, has in the end led a lot of people to writing things in a more functional style.


In my document I call it world but I'm going to change the name to context before I'm done.


The truth is, IMHO at least, that having to mock to test says something unfortunate about your code.


To unit test, that is.


It is obviously essential in OO, but if we get it right, it isn't in FP. But I'm still learning my trade.


Anyway, the core.async thing was just a passing thought.... the thing I do like about sagas as implemented in redux (and note that I am only a little way into understanding them) is that they let you write code that looks very synchronous.


I don;t think the method of getting there is important, and I'll read your doc more thoroughly to see what you're doing in that respect, but I think it's a pretty big plus.


A great example is where they talk about login flow...


In ES6 it boils down to:


function* loginFlow() { while (true) { yield take('LOGIN') // ... perform the login logic yield take('LOGOUT') // ... perform the logout logic } }


Now obviously in a real app it might be a little more complicated, but...


(an of course I'm omitting a bit of enclosing logic)


This feels like a fairly powerful thing. There's a flow to login and logout, but it's interpsersed with any number of other things. This lets us express this flow in one place.


And so many side-effecting things are like that.


As for still learning the trade... I've been programming for a long time now (if a bit lazily during some of that time,) and while it might be a bit immodest I think it's accurate to say that there is a small (but in some ways commercially important) niche of computer science where algorithms I devised are pretty much the state of the art. I'm still constantly humbled by the trade though, and coming back to doing web stuff after years of straight algorithmic work has humbled me anew.


I think re-frame is a really nice piece of work.


And while I don't know this for sure, I'd guess that it has served as inspiration for things that are being used very widely in JS-land these days.