On Wednesday, May 17, 2017 at 5:02:55 PM UTC+1, Christophe de Vienne wrote:
>
> The main thing that bothers me is that I will need to pass the 
> Nats.State to every update function because subscribing requires an 
> update of the state... And I see no way to avoid that except using an 
> effect module. 
>

So you would rather that your Nats module kept its own state 'private' and 
lets users of it send it a message asking to subscribe?

Suppose your code has 3 update functions and is structured like this:

Main (top-level update)
 - Nats (updates Nats State as websocket conversation progresses)
 - MyFunkyApp (does something cool. Needs to subscribe to Nats)

The TEA pattern that you could use to do this, whilst keeping the Nats 
state private, is to use an 'out message' from MyFunkyApp. Then have some 
routing in Main, that passes the subscriptions requests to Nats, where Nats 
can update its State in private.

It can be a lot of boilerplate if you have lots of modules using Nats, so I 
can see why the effects module approach is appealing.

===

I was eating breakfast this morning when it occurred to me that I may have 
a solution for you; it is an effects module:

https://github.com/rupertlssmith/elmq

If we divide your Nats implementation into two independant (orthogonal) 
parts - there is the websockets part, and there is a part relating to how 
you plumb this re-usable protocol module into an Elm application. The 
'elmq' effects module could solve the second part for you. This would mean 
that you don't need to write your own effects module for this specific 
problem as the concept has already been captured by the elmq effects module.

===

Here is an example of using elmq. Authentication is a very common component 
of applications and I also felt that it was likely that many modules in my 
applications would need to interact with authentication. In particular, I 
have quite a few Json web services over HTTP - at any time one of them may 
get back a 403 or a 401 and will then need to update the auth state to say 
that we are not currently authenticated.

To avoid all the 'out message' plumbing that would require, I built my auth 
module on top of elmq.

It provides an API, that stuffs event messages onto elmq channels:

https://github.com/rupertlssmith/elm-auth/blob/master/src/Auth.elm

And the AuthController is then able to subscribe to these messages, and 
privately update its state:

https://github.com/rupertlssmith/elm-auth/blob/master/src/AuthController.elm#L228

So you can see, it is very easy for a module to import the Auth API and use 
it, without having to worry about the plumbing needed to update the 
authentication state.

===

The elmq module was lifted from original code here: 
https://github.com/gdotdesign/elm-ui

One limitation of it is that you can only pass the primitive types or a 
Json.Encode.Value. Anything else you must provide an Encoder/Decoder for.

See the readme for elmq for some discussion points around how its API could 
be evolved. I would be very interested to hear if you think your use case 
fits it, or if you think it needs adapted a little to cater for your need? 
Would also be very happy to take suggestions on board and improve it.

It is not an official effects module, so you must install it with 
elm-github-install.

If it is useful to you, it might be time to consider making a proposal on 
elm-dev to push it towards becoming an official effects module. I have 
considered this before, but was not sure if it would be well received or 
not - its certainly quite a different way of doing things to the TEA 
approach. Also as Elm is single threaded, and this is really an 
asynchronous messaging model (like JMS for Java), does it make sense as a 
programming model for Elm? On the other hand, its very useful, so why not.


-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to