Re: [elm-discuss] Proposed addition for Task package

2016-11-23 Thread Magnus Rundberget
I'm definately with Wouter on this one.

Using tasks to do something that isn't a side-effect sounds much more like 
a code smell than using plain old function calls and function return values 
to compose your logic (when that is possible, which I would imagine would 
be true most of the time, if not all the time when there aren't any 
side-effects involved). 

I've seen this argument a while back related to people using a super nested 
TEA and getting tiered of boiler-plate (function calls and function return 
values), and using Tasks as a get out of jail card (for "child-parent", 
"child-sibling" etc communication).   Resorting to tasks might be Easy (at 
hand), but it's certainly not Simple (especially considering the 
asynchronous scheduler).

I respectfully disagree. Depending on the application, this either may not 
> be possible or would be a terrible code smell. I honestly think the above 
> suggestion would be worse than chaining another Cmd msg. Sending another 
> Cmd msg is clean and follows the Elm architecture.
>

It would be interesting to see some concrete examples of were it would not 
be possible or a code smell to use functions (rather than tasks) for 
non-side effecty things. Maybe I can be convinced.
  

Another case that wouldn't work out so well for is the init function. The 
> init function returns a (model, Cmd msg). I think it'd be much cleaner for 
> the init function to call sendMsg (or equivalent) instead of the init 
> function calling either my update function or the function that would be 
> called for that msg.
>

Why do you think that ? 

> ​
>>
>

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Charlie Koster

>
> The log then shows that between the DoStuff message and the DoMore 
> message, a Tick message comes in.
>

Well, that's troubling and undermines my assumption. That's for looking 
into this.

For those skimming through this post, *race conditions are possible when 
doing something like `*Task.perform (\_ -> GoToLoginPage) (Task.succeed 
Nothing)`

The fact that we do not agree on this, makes it an interesting discussion 
> here.

Where do others stand on this?


^^^ 

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Wouter In t Velt
For those interested: here is the example I refered to:
import Html exposing (..)
import Html.Events exposing (onClick)
import Time exposing (Time, second)
import Task

main =
  Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}

-- MODEL
type alias Model = { msgs : List String, timerOn : Bool }

init : (Model, Cmd Msg)
init =
  { msgs = []
  , timerOn = True
  } ! []

-- UPDATE
type Msg
  = Tick Time | DoStuff | DoMore


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Tick newTime ->
  { msgs = toString msg :: model.msgs
  , timerOn = True
  } ! []
  
DoStuff ->
  { model | msgs = toString msg :: model.msgs }
  ! [ send DoMore ]
  
DoMore ->
  { model | msgs = toString msg :: model.msgs, timerOn = False } ! []
  
  
send : msg -> Cmd msg
send msg =
  Task.succeed msg
  |> Task.perform identity


-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
  if model.timerOn then
Time.every 10 Tick
  else
Sub.none

-- VIEW
view : Model -> Html Msg
view model =
  div []
[ button [ onClick DoStuff ] [ text "click" ] 
, ul []
  <| List.map itemView model.msgs
]

itemView : String -> Html Msg
itemView string =
  li [] [ text string ]


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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Wouter In t Velt
Op dinsdag 22 november 2016 14:49:47 UTC+1 schreef Charlie Koster:
>
> My assumption is a race condition here wouldn't be possible since calling 
> `sendMsg MyMsg` is a synchronous action
>

I have tried it out in elm-lang.org/try, which suggests that it is 
asynchronous, in a simple setup
- button that sends a DoStuff message
- in update, the DoStuff branch outputs DoMore
- update also logs all messages
- the setup also contains a basic subscription to Time, with a Tick every 
10ms

The log then shows that between the DoStuff message and the DoMore message, 
a Tick message comes in.
This is an extreme example, I admit, but with subscriptions to server 
messages, mouseovers etc, there is no telling when messages come in.
So my takeaway was: if you want something done synchronously, handle it 
inside a single update cycle.

If the community agrees that using Cmd Msg as you suggest is a valid 
pattern with valid use cases, then the (simple) helper would be a useful 
addition to a Task (or Platform? or Platform.cmd) package.

The fact that we do not agree on this, makes it an interesting discussion 
here.
Where do others stand on this?

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Charlie Koster


> but I have seen terrible bugs being introduced by improper use, caused by 
> Cmd messages being created based on model state A, and because of race 
> conditions (e.g. fetch results coming in in the meantime)
>

My assumption is a race condition here wouldn't be possible since calling 
`sendMsg MyMsg` is a synchronous action and therefore would pipe through 
the Elm runtime and back into the update function immediately 
(synchronously). That's assuming that the Elm runtime doesn't do any 
setTimeouts behind the scenes that would allow for another Msg to be sent 
to the update function before MyMsg, thus making it asynchronous.

I agree that it's possible to misuse something like the above proposal, but 
I don't feel that should prevent it from going into core Task or core Cmd. 
Synchronously sending a Msg is a valid use case that Elm core could handle, 
and it does, but with less boilerplate.

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Wouter In t Velt
Op dinsdag 22 november 2016 13:47:55 UTC+1 schreef Charlie Koster:
>
> I respectfully disagree. Depending on the application, this either may not 
> be possible or would be a terrible code smell. I honestly think the above 
> suggestion would be worse than chaining another Cmd msg. Sending another 
> Cmd msg is clean and follows the Elm architecture.
>
I agree it depends on the application. Sometimes `Cmd msg` would be better, 
sometimes it would be worse. `Cmd msg` follows the Elm architecture, but I 
have seen terrible bugs being introduced by improper use, caused by Cmd 
messages being created based on model state A, and because of race 
conditions (e.g. fetch results coming in in the meantime), the call that 
the elm runtime made to the update function was with model state B. (when 
using Cmd, there is NO guarantee about the state of the model that the 
runtime will pass to the update function).

When I was beginning to learn Elm, this function was not around, and it 
forced me to learn more about TEA, Tasks, runtime etcetera.
Which in hindsight was IMHO a good thing.

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Charlie Koster

>
> One reason is what Evan says at 
> https://github.com/elm-lang/core/blob/master/CONTRIBUTING.md#adding-new-functions:
>  
> new functions are not so quickly expected to go into core, instead to be 
> accumulated in *-extra packages first.
>
I didn't realize that was the case. Thanks for the info.

it is better to do a recursive call to the `update` function, or better 
> yet: call the function that your command would call
>

I respectfully disagree. Depending on the application, this either may not 
be possible or would be a terrible code smell. I honestly think the above 
suggestion would be worse than chaining another Cmd msg. Sending another 
Cmd msg is clean and follows the Elm architecture.

Another case that wouldn't work out so well for is the init function. The 
init function returns a (model, Cmd msg). I think it'd be much cleaner for 
the init function to call sendMsg (or equivalent) instead of the init 
function calling either my update function or the function that would be 
called for that msg.

> ​
>

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-22 Thread Wouter In t Velt
My 2c:  I kind of like it that there is NOT such a function in the core.
Because it *prevents me from grabbing it when I really shouldn't*.

Especially if the `Cmd` has no side effects, it is better to do a recursive 
call to the `update` function, or better yet: call the function that your 
command would call, if it had been passed to the elm runtime.

Many of the names of the messages in the example suggest that creating a 
`Cmd msg` is not the best solution.

The only exception I can think of where it is useful is using 
`Process.sleep` to force a timeout.

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


Re: [elm-discuss] Proposed addition for Task package

2016-11-21 Thread Nick H


On Mon, Nov 21, 2016 at 7:04 PM, Charlie Koster  wrote:

> I'm a fan of the changes to Task.perform in Elm 0.18. However, I'm still
> finding that I'm writing a lot of boilerplate in some situations. For
> example, there are several instances when I want to send a msg which has no
> payload.
>
> Task.perform (\_ -> GoToLoginPage) (Task.succeed Nothing)
>
> I do this any time I am navigating to a different page, submitting a form,
> cancelling a form, kicking off any asynchronous request (logging in,
> CRUDing any data), and maybe one or two other special cases.
>
> I don't see any reason why not have a function in Task that takes a msg
> and returns a Cmd msg.
>
> sendMsg : msg -> Cmd msg
>
> Which could be used like this
>
> Task.sendMsg GoToLoginPage
> Task.sendMsg GoToOneOfTenOtherPages
> Task.sendMsg IsFetchingData
> Task.sendMsg IsUpdatingData
> Task.sendMsg IsCreatingData
> Task.sendMsg IsDeletingData
> Task.sendMsg CancelCreate
> Task.sendMsg CancelDelete
> Task.sendMsg LogoutSucceed
> ...
>
> Any thoughts on this proposed addition? Does anyone else find themselves
> writing a lot of boilerplate with Task.perform?
>
> --
> 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.
>

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


[elm-discuss] Proposed addition for Task package

2016-11-21 Thread Charlie Koster
I'm a fan of the changes to Task.perform in Elm 0.18. However, I'm still 
finding that I'm writing a lot of boilerplate in some situations. For 
example, there are several instances when I want to send a msg which has no 
payload.

Task.perform (\_ -> GoToLoginPage) (Task.succeed Nothing)

I do this any time I am navigating to a different page, submitting a form, 
cancelling a form, kicking off any asynchronous request (logging in, 
CRUDing any data), and maybe one or two other special cases.

I don't see any reason why not have a function in Task that takes a msg and 
returns a Cmd msg.

sendMsg : msg -> Cmd msg

Which could be used like this

Task.sendMsg GoToLoginPage
Task.sendMsg GoToOneOfTenOtherPages
Task.sendMsg IsFetchingData
Task.sendMsg IsUpdatingData
Task.sendMsg IsCreatingData
Task.sendMsg IsDeletingData
Task.sendMsg CancelCreate
Task.sendMsg CancelDelete
Task.sendMsg LogoutSucceed
...

Any thoughts on this proposed addition? Does anyone else find themselves 
writing a lot of boilerplate with Task.perform?

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