rgrempel / elm-route-url

Router for single-page-apps in Elm
http://package.elm-lang.org/packages/rgrempel/elm-route-url/latest
MIT License
196 stars 16 forks source link

Compatibility with Elm 0.17 #13

Closed rgrempel closed 8 years ago

rgrempel commented 8 years ago

I've taken a look at the information currently available about Elm 0.17, and it looks as though implementing elm-route-hash in Elm 0.17 is going to require a major re-architecture.

The distinctive feature of elm-route-hash (relative to other approaches to routing) is that it sits alongside your other program logic (rather than taking it over). You merely provide:

Given this, elm-route-hash can sit alongside your program logic, and (a) arrange for the URL to change at appropriate moments; and (b) send actions in response to URL changes.

The alternative approach would be to leave it to the program itself to generate "effects" (or, in Elm 0.17, "commands"), when you want to change the URL, among any other effects or commands your program generates. That is, you would generate URL changes as part of the logic of your update function, rather than in a separate function which is called in a distinct part of the signal graph.

The difficulty, of course, is that there is no signal graph in Elm 0.17. You still have an update function, which performs roughly the same purpose as in Elm 0.16. However, in Elm 0.17, Html.App arranges for calling your update function without exposing any abstraction that you could do anything else with.

I suppose that if one wanted something like Elm 0.16's signal of models, then Html.App would need to expose what Elm 0.17 calls a "subscription" to the model.

Absent that, the best we could do is provide some functions that can be called from your update function, which might return a command. We'd also have to re-architect the ways in which elm-route-hash had kept some state internally -- perhaps by requiring that you keep the state in your model, and provide it when needed.

Anyway, I'll investigate further -- just thought I'd jot down some initial thoughts.

amitaibu commented 8 years ago

What would be the downside of moving the logic to happen inside an update function? In a way it would might actually make it easier for new comers.

rgrempel commented 8 years ago

That's a good point ... it might not be so bad, really.

It would also mean that it wouldn't be necessary to "dispatch" a separate function down the component chain ... that is, one could mostly re-use the kind of dispatching from parents to children that the update function has to do anyway.

However, I'll probably won't be able to "hide" my internal state any longer -- the function the update function needs to call would have to be supplied with some state, and it would need to return some state that would need to be stored in the app's model (to be supplied again next time etc.). I can hide all of that in the signal graph at the moment, but without a signal graph ...

Anyway, we'll see -- I'll probably wait until @elm-lang publishes their planned History module, since that's probably what I'll have to build on.

amitaibu commented 8 years ago

Yeah, I've also just started looking at 0.17 - still need to figure how some stuff is going to work :)

rgrempel commented 8 years ago

I think what I might do is leave elm-route-hash as it is, and start a new module, perhaps called elm-route-url, or something like that.

Because (a) I'd like to support routing based on the full URL anyway (so the old name won't quite make sense), and (b) the new API and usage are likely to be so different that it may as well have a new name.

amitaibu commented 8 years ago

Sounds good

rgrempel commented 8 years ago

So, the Elm 0.17 navigation library is out:

http://package.elm-lang.org/packages/elm-lang/navigation/latest

I made some general comments on the mailing list:

https://groups.google.com/d/msg/elm-discuss/GqYFPIv-Quc/kf8vro6lGAAJ

As for how to adapt elm-route-hash, my preliminary thinking (as already noted above) is that it is going to be difficult -- probably impossible -- to re-implement the exact mechanisms that elm-route-hash used, because those mechanisms were so dependent on a relatively sophisticated manipulation of the signal graph, which isn't possible in Elm 0.17.

However, thinking about it from the point of view of a user of elm-route-hash, most of the existing code is essentially in location2action and delta2update. That is, the code written by users of elm-route-hash is essentially the implementation of those two functions. So, perhaps the most useful approach would be to try to write some kind of "shim" that would make those two functions fit within the new world. That seems possible to me -- there ought to be a way to make that work.

So, I'll give that a try, and see what I come up with.

rgrempel commented 8 years ago

It turns out that there is a technique that will permit me to re-implement essentially all of the logic of elm-route-hash in Elm 0.17. In short, it's something like this:

Since I would be wrapping your update function (among other things), I can pre-process and post-process things in a way that implements all the logic that elm-route-hash used to provide.

So, if you liked how elm-route-hash did things, I should be able to provide something very similar for Elm 0.17. I'm working on it now -- will probably be at least a few days to get it all figured out.

My plan is to provide something that matches the old elm-route-hash API as closely as possible, but also provide an alternate API that works with the Location as a whole, rather than just the hash.

rgrempel commented 8 years ago

I've now pushed up some work-in-progress that implements this.

However, it's untested -- my next task is to re-implement the examples, which should give me a chance to see if it actually works!

But, it seems conceptually sound, and it does compile ...

amitaibu commented 8 years ago

Would be great if you could also explain (in the readme?) the difference between this and the navigation module.

rgrempel commented 8 years ago

I've now updated the existing example code, and by golly, it basically works. I'll have to explore some edge cases more systematically, but it looks pretty good.

So, remaining to-do for version 2.0:

amitaibu commented 8 years ago

Great, looking forward for it -- I'm already eager to get elm-hedley ported to v0.17 :)

amitaibu commented 8 years ago

After playing with the navigation I appreciate even more this module, as it keeps almost the entire logic untouched. So one can build their app without the URL changes, and just add them after the fact. Not much refactoring of the existing code base is needed as init, update, view can stay the same.

rgrempel commented 8 years ago

I've published version 2.0.0 of elm-route-url, with Elm 0.17 compatibility.

amitaibu commented 8 years ago

Wonderful, much appreciated! :)