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?
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.*
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
- 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?
- How would you terminate a subscription?
- What happens if the process of establishing a subscription could fail?
- What is the best way to handle that?
- 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?
Sorry for the big bulk of text and thanks in advance!
--
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.