By writing this post, I may answer my own question, but anyway your opinions appreciated as always.
=== What is it?
As I have posted on here before, I pulled this library:
https://github.com/rupertlssmith/elmq
Out of the elm-ui code here:
The idea is that if you have nested update functions in several modules:
Main.update
Child1.update
Child2.update
..
And you also have nested subscriptions:
Main.subscription
ChildA.subscription
ChildB.subscription
..
Where the 2 sets (1..n) and (A.._), may have an intersection. The elmq library provides a convenient way for the child modules to talk to one another, based on using named 'channels'. Here is a little example:
module Child1 exposing (..)
import Elmq
-- To send string messages to the "chat.elm" channel.
elmTalk : String -> Cmd msg
elmTalk message =
Elmq.sendString "chat.elm" message
module ChildA exposing (..)
-- To receive string message on the "chat.elm" channel
type Msg =
ReceiveChat String
subscriptions : Model -> Sub Msg
subscriptions model =
Elmq.listenString "chat.elm" ReceiveChat
It is implemented as an effects module; there is a little routing engine that processes the Cmds and turns them into Subs, where matching senders and listeners on the same channel.
=== Why?
Very early on in my learning with Elm, I did not know what an 'out message' is. People tried to point me in this direction, I was confused and there was just too much to get my head around.
I pulled out the auth code from an application I wrote, and wanted to re-use it. It is very convenient to be able to easily invoke 'unauthed : Cmd msg' from anywhere in an application without having to worry about a specific out message type, and having to implement the routing logic for the auth out messages in the Main.update of every application I write seemed like it would be a pain. I just wanted to encapsulate auth as a re-usable thing that I can drop into any application I write.
Working with something with the type 'Cmd msg' seems easier than working with an extra out message type, since update functions tend to return Cmds anyway.
Out message are considered a little awkward in Elm - we often feel we are having to write a lot of boiler plate to pass them up the chained update functions.
== What are the potential benefits?
There is a generic message router - that logic does not need to be re-implemented in every Main.update, I ever write.
The concept of channels can be useful for more dynamic routing. Channels can come and go. This feature may actually prove to be useful, but I don't actually have an application that needs it.
== Why reconsider it?
Now that I sat through Richard Feldman's talk, I know that even the generic concept of 'out messages' can be too wide. If you have a nested update function that needs to return something, just return it. If it needs to return lots of things, those things may get enumerated as a tagged union - or the design might be wrong.
Elmq does not really solve the boilerplate issue that nested update and subscriptions present. For example in my Main.update I am still using Cmd.map to lift child messages to the main Msg type, and in Main.subscription I am still Sub.map to forward the subscriptions to child modules. This made me realise that all I am really doing with elmq is hacking Cmd and Sub to work as a generic out message types - I may as well just declare my own ElmqMessage type, pull the routing logic out of the effects module and run it in the application instead.
I can't publish effects modules. Using elmq means I can't publish other things I have done that depend on it.
== How to fix my code?
As above, make my own ElmqMessage type and pull the routing logic out of the effects module. This would result in a message router that retains the dynamic routing capability, should anyone ever need such a thing.
Narrow the types of the auth messages that my applications need - that is, don't use my own generic ElmqMessage type, just narrow it to the specific things that auth needs - type AuthMsg = LogIn | LogOut | Refresh | Unauthed. Have the auth module expose an update function that is specific to this type, update : AuthMsg -> AuthState -> AuthState.
Get back within the Elm 0.18 platform, and be able to share my wondrous projects with you all. Thanks for reading, if you get this far.