Comments i
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas wrote:
>
> Hi everybody! I've been reading the docs and following Elm every now and
> then. I did some toy application to learn the language and the
> architecture. I am working on a native iOS application so using Elm in my
> day job won't happen (for now). The main reason I want to learn Elm (apart
> from it being awesome!) is that I want to apply Elm's architecture to iOS
> with Swift (yeah a lot of people is doing the same thing). There are quite
> a few libraries that try to bring Elm's architecture to Swift but I don't
> want to use them. I want to implement something myself because that way I
> will be able to understand it better.
>
> The reason I am writing is that I want to better understand how
> subscriptions work internally. Please correct me if I am wrong. My
> understanding of how subscription works is that they provide a mechanism to
> "hook" to a stream of infinite events. Those events get mapped to your own
> application message by virtue of the message constructor function that is
> passed when creating a new subscription. As far as I can tell the only way
> of creating subscription is by a model update. Every time the model gets
> updated, Elm's runtime calls the subscription function (passed to the init
> function when you bootstrap your app). This gives us the change to create a
> new subscription based of the current state. Am I correct?
>
> - Is there any other way of creating subscriptions?
> - What happens when the process of starting a subscription needs to
> perform a expensive side-effect?
> - What is the Elm way of doing this?
>
> No other way of creating subscriptions.
The subscription itself should be fairly minimal, the effect manager
handling the subscription setup and teradown should be doing all the costly
stuff 'out-of-band' of your main app.
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
> Lets say that I have an application that connects to an external device
> and after connecting with this device it wants to start listening to a
> stream of data that this device reports every one second. Lets imagine this
> device is thermometer that advertises the room's temperature. I want to
> have an app that prints the average temperature since a connection with
> thermometer was established. We can omit how we connect with thermometer
> for now
>
> type alias Model =
> { thermometer: Maybe Thermometer
> , temperatureSamples: List Float
> }
>
>
> type Msg
> = ConnectedThermometer Thermometer
> | TemperatureSample Float
>
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
> case msg of
> ConnectedThermometer thermometer ->
> ({ model | thermometer = thermometer }, Cmd.none)
>
>
> TemperatureSample temperature ->
> ({ model | temperatureSamples = temperature :: model.
> temperatureSamples}, Cmd.none)
>
> view : Model -> Html Msg
> view model =
> let
> averageTemperature = (List.sum model.temperatureSamples) / List.length
> model.temperatureSamples
> in
> Html.text (toString averageTemperature)
>
>
> subscriptions : Model -> Sub Msg
> subscriptions model =
> model.thermometer
> |> map Thermometer.temperature TemperatureSample
> |> withDefault Sub.none
>
>
> -- Inside the Thermometer module
> temperature : (Float -> Msg) -> Thermometer -> Sub Msg
> temperature msgConstructor thermometer = ...
>
>
> *I am assuming there is a function in the Thermometer that knows how to
> create subscription for a given connected thermometer. I am also assuming
> that this MUST be implemented in Javascript and that all needed
> side-effects in order to create the subscription are performed on the JS
> side.*
>
Nah, subscription can be managed within Elm by an effect manager (though it
tends to eventually go out to a javascript effect manager, like via HTTP
requests or whatever).
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
> If my assumptions are correct then my main concern is that for every state
> update this "expensive" side effects that could be performed on the JS side
> by creating a new subscription are executed for every model update. If that
> is the case then I have the following questions
>
A subscription is just that, a subscription, saying that you 'want to
listen to messages from a given effect manager'. The remote effect manager
could even be doing stuff even when nothing is subscribed, a subscription
is just that the main app wants to listen to messages from that effect
manager. Subscriptions should change only based on your state. Basically
it works kind of like this:
1. You have a subscription that appears when something on your model is,
say, True.
2. The system sees that a new subscription has appeared compared to the
last check, so it calls into the effect manager (passing it a
'registration' message basically), and the effect manager can do whatever
it wants, from storing it, ignoring it, whatever.
3. As the effect manager does stuff (receives something over a http
request, gets an interval call from the javascript setInterval, whatever),
it calls the 'router' to send a message back to the main application, which
the application handles via the subscription callback.
4. When the subscription is no longer registered in the main app the effect
manager gets a notification of that via another message to it.
Basically for a given thermometer thing, the setup should generally either
be a task or an effect manager itself, depending on what and how much it
does.
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas wrote:
>
> - Is the responsibility of the JS code that creates the subscriptions
> to keep track of the created subscriptions and avoid creating a new one if
> a previous subscription to the same thermometer has already been created?
>
> Nope that is the job of the effect manager that is registered too (which
is sometimes but not always backed by JS code).
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
>
> - How would you terminate a subscription?
>
> Just quit registering to it, the effect manager backing it will tell the
effect manager that it is no longer interested in messages.
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
>
> - What happens if the process of establishing a subscription could
> fail?
>
> You could do that via a Task, get a valid or invalid connection (then pass
the connection to a subscription to listen to updates from it), or that
could be handled by the effect manager itself too, it makes a connection
when a subscription starts and so forth, it can send a failure message
(Result or some custom union type) if it fails for example.
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
>
> - What is the best way to handle that?
>
> See above.
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
>
> - Do I need to execute a command to perform the side effect (which
> could possible fail) that would allow to create a subscription and if and
> only if this command is successfully executed then try to create a
> subscription?
>
> Only if you want, but honestly I'd put that job in the effect manager
itself...
On Tuesday, November 15, 2016 at 2:02:10 PM UTC-7, Guido Marucci Blas
wrote:
> Sorry for the big bulk of text and thanks in advance!
>
And do note, I use Elm in a large project, but I do not do dev work on elm
itself, my knowledge is no doubt incomplete but I have decently implemented
the Elm API (subscriptions and all) in other languages (of which it works
wonderfully in) so I hope my knowledge is fairly accurate. ;-)
--
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.