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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.