Let's take a step back, here.

Conceptually, the `init` function is meant to say how to jumpstart your 
application. So what it should do, is provide the initial state of your 
model, and - optionally - telling the runtime to start executing some 
asynchronous task right away (a good example would be fetching some remote 
resource), as a Cmd.

When the runtime receives such a Cmd, it will do what your commanded it to 
do, and then call your `update` function with the current state of the 
model and the Msg that resulted from your Cmd.

Using `Task.perform` with a "no op" task to "trick" the runtime into 
calling your update feels wrong, as you say yourself. I'd argue that it's 
definitely abusing the the runtime, too.

So, let's have a look at what you are trying to accomplish: you want to 
execute a function on your model, before declaring it "final". You could do 
that by calling `update` with the appropriate Msg from your init function, 
*or* you could split off that branch into a proper function that transforms 
your model.

What you'd end up with, then, is something like this:

```
init : (Model, Cmd msg)
init =
 ( initialModel |> transformIt, Cmd.none)
```

Your update function would call that exact same function - which means you 
could think of the update function like a sort of "translation" from 
messages to function calls that transform your model, rather than the one 
central place to bundle all your logic.

Hope this helps :)

Kr,

Ilias

Op woensdag 8 maart 2017 22:50:00 UTC+1 schreef Duane Johnson:
>
> Preface: while I've been using Elm for a while, I've only just begun using 
> messages and commands, so it's ok to treat me like a newbie here. This is a 
> capture of my experience of Elm while trying to figure out how to send an 
> initial message.
>
>
> I find the `Cmd` type a little confusing, especially in the init function. 
> Conceptually, I want to "kick off" an initial fetch of data from client to 
> server, and it would make intuitive sense if I were permitted to do this:
>
> ```
> init : (Model, Msg)
> init =
>     { initialModel, FetchStatus 0 }
> ```
>
> But instead, the type of `init` is required to be this:
>
> ```
> init : (Model, Cmd Msg)
> init =
>     { initialModel, ... }
> ```
>
> When I get to this point, I need to look up the documentation on Cmd. 
> Having read the guide several months ago, I have a vague impression that I 
> may need to "perform" something to get my message into a Cmd type. I look 
> at the `Platform.Cmd` documentation, and I see there's a `Cmd` type which 
> looks like a constructor. So I try this:
>
> ```
> init : (Model, Cmd Msg)
> init =
>     { initialModel, Cmd (FetchStatus 0) }
> ```
>
> But I get an error: "Cannot find variable `Cmd`". Having some experience 
> with Elm, I believe this may mean although Cmd is a type, its constructor 
> is not exposed.
>
> At this point, the `map` function looks a little promising, because it 
> takes some things that are not Cmd and produces `Cmd msg`, i.e. precisely 
> the type I'm looking for. However, it's not clear to me what the first 
> parameter to map is (a function that takes `a` and produces `msg`?) There's 
> no documentation on this `map` function.
>
> Then I peruse the docs some more ("maybe this is so common a thing that it 
> belongs in Basics? or maybe I missed something in Platform, since Cmd is a 
> submodule of Platform?") and arrive at the Task documentation, where I see 
> the "perform" signature:
>
> perform 
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Task#perform> : 
> (a -> msg) -> Task 
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Task#Task> Never 
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#Never> a 
> -> Cmd 
> <http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Platform-Cmd#Cmd> 
> msg
>
> This looks promising as well, because it takes some things and produces a 
> `Cmd msg`. But the example in the documentation shows how to use `perform` 
> with `Time.now` which further confuses things because I just want to pass a 
> Time value to my FetchStatus, like it was meant to receive (not necessarily 
> a "now" value). If I try this:
>
> ```
> init : ( Model, Cmd Msg )
> init =
>     ( initialModel, Task.perform FetchStatus 0 )
> ```
>
> I get
>
> ```
> Function `perform` is expecting the 2nd argument to be:
>     Task.Task Never Time
> ```
>
> So finally I realize that I need to pass a "succeed" task to my `perform` 
> call so I can create a `Cmd msg` of the type I need:
>
> ```
> init : ( Model, Cmd Msg )
> init =
>     ( initialModel, Task.perform FetchStatus (Task.succeed 0) )
> ```
>
> Subjectively, this all feels more convoluted than it needs to be. At a 
> basic level, I want to communicate an initial model and an initial "kick 
> off" message. It's confusing that Task types are involved in constructing 
> Cmd types. This makes finding the right documentation difficult. In 
> addition, it isn't clear why a Cmd is needed at all--why not a Msg, or a 
> List Msg? Conceptually, this would be a lower barrier to entry.
>
> This is just a running journal of my experience trying to do a basic Elm 
> task (no pun intended). I hope it helps make the Elm experience better in 
> some way for others.
>
> Best,
> Duane
>

-- 
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