[elm-discuss] Re: What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread John Bugner
Coming from Haskell, some things that haven't been mentioned yet: 
(1) Learning to embrace pattern matching, especially in situations where 
you don't have to in Haskell, like getting the first item of a list. (In 
Haskell, `head` returns `a` instead of `Maybe a`, so you can just check 
whether the list is empty, and if it isn't, use `head`.)
(2) Learning what to use instead of guards and `where` clauses.
(3) Learning how to live without (type)classes. Aka, learning how to hide 
direct imports (`map`), and instead use qualified imports (`List.map`, 
`Dict.map`, `String.map`, etc) to tell them apart.
(4) Learning the command/subscription idiom (and before that, signals).

I note that after learning to do things the Elm way, it becomes clear that 
Elm is indeed doing things "the right way". I really appreciate that Elm is 
willing to break with earlier programming traditions in order do things the 
right way. (I do miss (type)classes just a little bit though.)

>I'd say learning how to make illegal states unrepresentable.
Indeed. Compare making a simple binary tree in Elm/Haskell to making one in 
the imperative-OO language of your choice. Learning to use `Maybe` 
correctly (and thus realizing how imp-OO languages do `null` all wrong) is 
a subset of this.

On Thursday, August 11, 2016 at 4:07:33 AM UTC-5, Peter Damoc wrote:
>
> "The fundamental fact about learning: Anything is easy if you can 
> assimilate it to your collection of models. If you can't, anything can be 
> painfully difficult.” - Seymour Papert
>
> I'm trying to come up with a sorted list of concepts and models that a 
> prospective Elm user needs to learn in order become proficient in Elm. 
>
> Here is my list (I actively tried to keep it short) : 
>
> - types : the concept that information flowing through an Elm program has 
> a specific type and that the compiler will not accept the wrong type. 
>
> - type composition: the concept that types can be composed into more 
> advanced types using union type syntax and record syntax. 
>
> - type variables : the concept that you can have a type constructor that 
> can take arguments and produce a custom type (List, Maybe, etc) 
>
> - functions as types: the concept that you can give functions to other 
> functions in order to customize their application. 
>
> - currying/closures: the concept that you can take a multi argument 
> function and produce another function that has some of those arguments 
> applied. 
>
> - declarative: the concept that the Elm programs are made of one big 
> function that returns a specific type instead of a series of instructions.  
>
> How does your list looks like? Which one gave you most troubles? Which one 
> did you find most  amazing | useful | mind-blowing ? 
>
>
>
>  
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
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] Re: about the Keyboard API

2016-08-11 Thread Janis Voigtländer
Okay, this keyMap* suggestion would need more scrutiny. Being a more
radical departure from the current API, it is not obvious that all current
Keyboard uses would still be well supported.

I will open an issue in the Keyboard repository with my more incremental
API proposal.
​

2016-08-11 18:48 GMT+02:00 OvermindDL1 :

> Heh, yes I keep putting different ideas here, I am not focusing on a
> single idea, just working with the API's in testing a bit, figure out some
> new ideas, and document them here, upon which I then go out, make a mock-up
> of the ideas, and see how it works and document the results again.  Just a
> set of ideas for others to mull over as well to see if anything has merit.
> And yep, the latest Keyboard.keyMap* could be a replacement of the existing
> API (or added to it).  From my mock testing it seems to be the easiest to
> use and most configurable thus far for this specific issue (since it is
> entirely just a simple-to-read-and-parse data structure without a host of
> mis-matched calls).
>
>
> On Thursday, August 11, 2016 at 9:58:28 AM UTC-6, Janis Voigtländer wrote:
>>
>> You throw in a lot of different ideas. I’m getting confused.
>>
>> Concerning the approach with having both subscriptions and your new
>> filters hook, I still think what I wrote in my last message (about the
>> case if you were to make the same decisions as the original code about
>> which subscriptions are running when, particularly concerning the animation
>> frame ticking):
>>
>> However, the result will be again more complex and less readable, I
>> think. You will have the dealing with subscriptions distributed over
>> different places in the code, while the original version and also the
>> version improved by selective Keyboard functions has only one.
>>
>> Your new message does not seem to try to rebut this. Instead, it proposes
>> a completely different route? The Keyboard.keyMapChar and
>> Keyboard.keyMapFn etc. things. This would be intended as completely
>> replacing the current Keyboard API? As a more radical proposal than just
>> changing the types of the current Keyboard.downs etc. functions by
>> bringing Maybe into play?
>> ​
>>
>> 2016-08-11 16:51 GMT+02:00 OvermindDL1 :
>>
>>> The ticks did change yes, I originally had it testing the state first
>>> but figured, eh, I was wanting to see what a keyboard action mapper would
>>> be (which could easily be fed into a Keyboard mapper, ignore the filters
>>> stuff).
>>>
>>> I still find mapping the keyboard events 'inside' subscription to be
>>> very noisy.  And I still think think a single subscription for a keyboard
>>> filter would be best to prevent running and testing multiple.  Hmm, maybe
>>> something like:
>>> ```elm
>>>   Keyboard.keyMapChar
>>> case d.state of
>>>   Running ->
>>> [ ( 'P', KeyDown, PauseToggle )
>>> , ( ' ', KeyDown, JumpDown )
>>> , ( ' ', KeyUp,   JumpUp )
>>> ]
>>>   _ ->
>>> [ ( 'P', KeyDown, PauseToggle )
>>> ]
>>> ```
>>>
>>> I am one of those that hate inline conditionals and prefer to hoist it
>>> out, so yes I like the duplicated PauseToggle, makes it explicitly obvious
>>> that it is working in each state instead of noise like ++ and such making
>>> you have to think more.  However I think that is wonderfully readable and
>>> could easily register and unregister subscriptions as needed while making
>>> configurable key mapping much easier (since no need to convert to if/then
>>> repeating or dict lookups or so).
>>>
>>> Or as a full example the above could be:
>>> ```elm
>>> subscriptions : GameData -> Sub GameMsg
>>> subscriptions =
>>>   case d.state of
>>> Running ->
>>>   Sub.batch
>>> [ AnimationFrame.diffs Tick
>>> , Keyboard.keyMapChar
>>>   [ ( 'P', KeyDown, PauseToggle )
>>>   , ( ' ', KeyDown, JumpDown )
>>>   , ( ' ', KeyUp,   JumpUp )
>>>   ]
>>> ]
>>> _ -> Keyboard.keyMapChar [ ( 'P', KeyDown, PauseToggle ) ]
>>> ```
>>>
>>> Which I also think is far more readable (embedding state tests are
>>> always unreadable).
>>>
>>> A `Keyboard.keyMapFn` could also make the first element of the tuple be
>>> a function that is passed in a keycode so it can do its own testing via
>>> returning True/False.  Or could just make it a `Keyboard.keyMap` where
>>> the first element is a subtype to become `( KeyMap.Char 'P', KeyDown,
>>> PauseToggle )` or `KeyMap.Fn` or whatever other options.  Would make it
>>> easier to expand later as well with more functionality if ever desired.
>>>
>>> As always, lots of ways to go with various designs.
>>>
>>>
>>> On Wednesday, August 10, 2016 at 8:53:32 PM UTC-6, Janis Voigtländer
>>> wrote:

 You did change the behavior, though. Specifically, AnimationFrame.ticks
 is always running in your version, even when the game is paused. Similarly
 for some of the other subscriptions. As discussed in the generic
 subscription filtering thread, it'

[elm-discuss] Re: [ANN] elm-mdl 7.0.0 — supports all components of Material Design Lite

2016-08-11 Thread Mohamed Chenini
Hi,   Is there a component that can simulate an accordion?

On Wednesday, August 3, 2016 at 6:07:00 PM UTC-4, debois wrote:
>
> Dear all,
>
> I'm very happy to announce the release of elm-mdl 7.0.0. This release 
> marks a substantial achievement of elm-mdl: we have now ported *every* 
> component 
> of Google's Material Design Lite 
> !
>
> Live demo here , package here 
> , github here 
> .
>
> The release contains 6 new components: Cards, Lists, Dialog, Tabs, Sliders 
> & Typography; a large amount of bugfixes, in particular wrt. browser 
> compatibility; improved documentation; and substantial improvements to the 
> demo.
>
> The release requires minor changes to your elm-mdl boilerplate; details 
> here 
> 
> .
> Credits
>
>- 
>
>Rob van den Bogaard (@robvandenbogaard 
>), new contributor. 
>Cards component. Rob created a very neat API for Cards, which in turn 
>inspired the Dialog API.
>- 
>
>Håkon Rossebø (@hakonrossebo ), 
>regular contributor.
>Lists component. Håkon paved the way for solving some thorny issues in 
>finding a good API for lists, the upstream API of which doesn't sit so 
> well 
>with Elm.
>- 
>
>Michael Perez (@puhrez ), new contributor.
>Dialog component. Michael took Rob's Cards API-idea and ran with it, 
>arriving at a very neat API for Dialogs.
>- 
>
>Ville Penttinen (@vipentti ), core 
>contributor, commit-rights. 
>Tabs, Sliders, and Typography components; lots of demo work; lots of 
>bugfixes. Ville provived a remarkbly high-quality sustained contribution.
>- 
>
>Alexander Foremny (@aforemny ), core 
>contributor, commit-rights.
>Bug fixes and improvements to menu. Alexander also participated 
>crucially in discussions, taking a large part in guiding the overall 
>direction of elm-mdl.
>- 
>
>Stéphane Legrand (@slegrand ), new 
>contributor. 
>Bug-fixes for ripples, documentation improvements.
>- 
>
>Søren Debois (@debois ), original author. 
>Bug fixes galore; assisted on Cards, Lists, Dialogs, Typography, and 
>Menus; lots of demo work.
>
> Thanks to Google for making their JS/CSS MDL implementation available.
>
> Supporting all components of Google's MDL is obviously a huge milestone 
> for elm-mdl. I could never have reached this point by myself; I'm so happy 
> and grateful that so many people chose to devote their time and energy to 
> this project. So a *huge* thank you to all of you who contributed to 
> elm-mdl, to this release or earlier ones:
>
>- Core team: Alexander Foremny (@aforemny ), 
>Ville Penttinen (@vipentti )
>- Component implementations: Michael Perez (@puhrez 
>), Rob van den Bogaard (@robvandenbogaard 
>), Håkon Rossebø (@hakonrossebo 
>)
>- Demo work, features & bug-fixes: Victor Vrantchan (@groob 
>), @SauceWaffle 
>, Stéphane Legrand (@slegrand 
>), Petre Damoc (@pdamoc 
>)
>- Documentation: Janis Voigtländer (@jvoigtlaender 
>), Rudolf Adamkovič (@salutis 
>), Alexey Shamrin (@shamrin 
>), Matthew Bray (@mattjbray 
>)
>
> Also a big thank you to all those who are using elm-mdl; who has 
> encouraged me in the elm-slack and on elm-discuss; and who has taken the 
> trouble to open github issues: your kindness and encouragment has been a 
> big part in getting to this point. I want to mention in particular early 
> adopter @groob  and issue-author extraordinaire 
> @OvermindDL1 .
>
> Thank you, all, for helping get elm-mdl this far!
>
> Søren Debois
>
>

-- 
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] Is it possible to render an HTML form that works directly?

2016-08-11 Thread Aaron VonderHaar
Maybe you could render the form inside of an iframe so that the redirecting
would happen within the frame and maybe you could detect that somehow?

On Wed, Aug 10, 2016 at 8:55 AM, Simon  wrote:

> This is related to https://groups.google.com/forum/#!topic/elm-discuss/
> M6vbRoVSaG4 in that I'm trying to find work arounds to do signed uploads
> to S3.
>
> In short, can I use Elm to render a POST form with a `file` input and a
> submit button that 'just works' - i.e. the POST takes place directly and
> uses the browsers filereader and multipart building functionality directly,
> with Elm just sitting back and watching it happen?
>
> I think the answer is yes, but I'l be left with no control over the
> browser's subsequent redirecting. Any ideas on whether that can be
> caputured and turned into an event that can be passed back to Elm through a
> port?
>
> --
> 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] Re: What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Ian Mackenzie
The most important one I keep coming back to is the design principle of 
rigorously separating functions and data - don't keep functions in your 
model, etc.

In many ways I jumped on Elm just because it felt so immediately *right* 
and natural, as opposed to "I heard Elm was great but now I have to adjust 
to a whole new way of thinking", so there wasn't a lot of mental 
gymnastics. But coming from C++ (and more recently Scala) I still started 
out doing things like creating 'interface types' that were records with a 
couple of function fields and passing those around as arguments to other 
functions.

I guess the other one would be getting used to function signatures and 
currying. Simple examples like plus : Int -> Int -> Int are relatively easy 
to explain as "it can take two Ints and return an Int, or take one Int and 
return a new Int -> Int function" but I still find some cases a bit 
mind-bending especially when type aliases get involved - here's some helper 
code I recently wrote:

type alias Comparator a =
a -> a -> Bool


both : Comparator a -> Comparator a -> Comparator a
both firstComparator secondComparator first second =
firstComparator first second && secondComparator first second

So the both function is declared as taking two comparator functions and 
returning another comparator function, but thinking of it in those terms 
the implementation actually takes the first two functions *and the two 
arguments of the resulting function*, and returns the final result. It all 
makes sense if you mentally 'flatten' the type signature and think about 
partial application a bit, but at first glance it seems odd.

On Thursday, 11 August 2016 19:07:33 UTC+10, Peter Damoc wrote:
>
> "The fundamental fact about learning: Anything is easy if you can 
> assimilate it to your collection of models. If you can't, anything can be 
> painfully difficult.” - Seymour Papert
>
> I'm trying to come up with a sorted list of concepts and models that a 
> prospective Elm user needs to learn in order become proficient in Elm. 
>
> Here is my list (I actively tried to keep it short) : 
>
> - types : the concept that information flowing through an Elm program has 
> a specific type and that the compiler will not accept the wrong type. 
>
> - type composition: the concept that types can be composed into more 
> advanced types using union type syntax and record syntax. 
>
> - type variables : the concept that you can have a type constructor that 
> can take arguments and produce a custom type (List, Maybe, etc) 
>
> - functions as types: the concept that you can give functions to other 
> functions in order to customize their application. 
>
> - currying/closures: the concept that you can take a multi argument 
> function and produce another function that has some of those arguments 
> applied. 
>
> - declarative: the concept that the Elm programs are made of one big 
> function that returns a specific type instead of a series of instructions.  
>
> How does your list looks like? Which one gave you most troubles? Which one 
> did you find most  amazing | useful | mind-blowing ? 
>
>
>
>  
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
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] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Checked the current implementation of Cmd.batch and it appears sequential 
(`mailbox.push`). Ordering guarantees are not documented so I suppose they 
shouldn't be depended on. But otherwise, the one I coded above that 
guarantees Act doesn't change the model and Evt doesn't have effects would 
work.

On Thursday, August 11, 2016 at 6:33:39 PM UTC-5, Kasey Speakman wrote:
>
> Yes, that's why I said back to square one if Cmd.batch isn't ordered. The 
> only thing this is guaranteeing (and the only intended guarantee) is that 
> the messages which only update the model are separated from the ones which 
> cause effects. The ones which cause effects produce ones which update the 
> model, same as always.
>
> It occurs to me that some of the benefit of event sourcing the UI could be 
> gained by adding features to the TTD, since it has the magic which ignores 
> Cmds on replay. Some are already listed as ideas at 
> http://debug.elm-lang.org/. I'd still have to keep the messages in my 
> model and provide a way for the user to transmit them in a bug report. But 
> if I could load them in the TTD, that would make repro a snap.
>
> On Thursday, August 11, 2016 at 5:22:05 PM UTC-5, OvermindDL1 wrote:
>>
>> Isn't `doSideEffects` basically just the current `update` function 
>> though?  Except it is returning a list of changes (via message) to perform 
>> to a model instead of doing it in-place?  What is this saving precisely?
>>
>>
>>
>> On Thursday, August 11, 2016 at 4:05:57 PM UTC-6, Kasey Speakman wrote:
>>>
>>> Actually, I'd probably use a List instead of Maybe on the immediately 
>>> returned event(s).
>>>
>>> doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
>>> doSideEffects act model = 
>>>   case act of
>>> UpdateCustomer customer ->
>>>   ( [ CustomerUpdateRequested ]
>>>   , callServerWithCustomer customer
>>>   )
>>>
>>> ...
>>>
>>> updateModel : Evt -> Model -> Model
>>> ... -- implementation as previous
>>>
>>> update : Msg -> Model -> (Model, Cmd Msg)
>>> update msg model =
>>>   case msg of
>>> Action act ->
>>>   let
>>> (events, command) = doSideEffects act model
>>>   in
>>> (List.foldr updateModel model events, Cmd.map Evt command)
>>>
>>> Event evt ->
>>>   (updateModel evt model, Cmd.none)
>>>
>>>
>>>
>>> On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:

 Yes, that was the goal. That way the UI state is utterly deterministic 
 / reproducible in isolation of all outside services.

 That's a good point on the race conditions. I only use Cmd.batch 
 because it's the facility that came to mind. (I'm still getting acquainted 
 with Elm.) I don't know if Cmd.batch makes any ordering guarantee.

 If not we'd be more or less back to square one. Abuse `update` to do 
 both things.

 doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
 doSideEffects act model =
   case act of
 UpdateCustomer customer ->
   (Just CustomerUpdateRequested, callServerWithCustomer customer)

 ...

 updateModel: Evt -> Model -> Model
 ... -- implementation as previous

 maybeUpdateModel:  Maybe Evt -> Model -> Model
 maybeUpdateModel evtOpt model =
   case evtOpt of
 Nothing ->
   model

 Just evt ->
   updateModel evt model

 update : Msg -> Model -> (Model, Cmd Msg)
 update msg model =
   case msg of
 Action act ->
   let
 (eventNow, command) = doSideEffects act model
   in
 (maybeUpdateModel eventNow model, Cmd.map Evt command)

 Event evt ->
   (updateModel evt model, Cmd.none)

 So this should apply an event immediately if one is needed for the 
 action. But it still keeps the model updating events separate.

 These immediate events would be seen by a userland event-store 
 implementation (which is underneath updateModel), but I bet the TTD 
 wouldn't see it since it doesn't come from Elm.

 On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>
> So you really are wanting to hard device events into two different 
> ones, those that can *only* alter the model, and those that can *only* 
> send 
> commands (which may call ones that alter the model).  Unsure if it might 
> actually happen but might have to take into account possible race 
> conditions for if other messages appear before your other expected ones 
> are 
> processed through?  Easier to do that atomically all at once?
>
>
> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>>
>> doSideEffects above would also have to map Cmd Evt to Cmd 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, s

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Yes, that's why I said back to square one if Cmd.batch isn't ordered. The 
only thing this is guaranteeing (and the only intended guarantee) is that 
the messages which only update the model are separated from the ones which 
cause effects. The ones which cause effects produce ones which update the 
model, same as always.

It occurs to me that some of the benefit of event sourcing the UI could be 
gained by adding features to the TTD, since it has the magic which ignores 
Cmds on replay. Some are already listed as ideas at 
http://debug.elm-lang.org/. I'd still have to keep the messages in my model 
and provide a way for the user to transmit them in a bug report. But if I 
could load them in the TTD, that would make repro a snap.

On Thursday, August 11, 2016 at 5:22:05 PM UTC-5, OvermindDL1 wrote:
>
> Isn't `doSideEffects` basically just the current `update` function 
> though?  Except it is returning a list of changes (via message) to perform 
> to a model instead of doing it in-place?  What is this saving precisely?
>
>
>
> On Thursday, August 11, 2016 at 4:05:57 PM UTC-6, Kasey Speakman wrote:
>>
>> Actually, I'd probably use a List instead of Maybe on the immediately 
>> returned event(s).
>>
>> doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
>> doSideEffects act model = 
>>   case act of
>> UpdateCustomer customer ->
>>   ( [ CustomerUpdateRequested ]
>>   , callServerWithCustomer customer
>>   )
>>
>> ...
>>
>> updateModel : Evt -> Model -> Model
>> ... -- implementation as previous
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Action act ->
>>   let
>> (events, command) = doSideEffects act model
>>   in
>> (List.foldr updateModel model events, Cmd.map Evt command)
>>
>> Event evt ->
>>   (updateModel evt model, Cmd.none)
>>
>>
>>
>> On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:
>>>
>>> Yes, that was the goal. That way the UI state is utterly deterministic / 
>>> reproducible in isolation of all outside services.
>>>
>>> That's a good point on the race conditions. I only use Cmd.batch because 
>>> it's the facility that came to mind. (I'm still getting acquainted with 
>>> Elm.) I don't know if Cmd.batch makes any ordering guarantee.
>>>
>>> If not we'd be more or less back to square one. Abuse `update` to do 
>>> both things.
>>>
>>> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
>>> doSideEffects act model =
>>>   case act of
>>> UpdateCustomer customer ->
>>>   (Just CustomerUpdateRequested, callServerWithCustomer customer)
>>>
>>> ...
>>>
>>> updateModel: Evt -> Model -> Model
>>> ... -- implementation as previous
>>>
>>> maybeUpdateModel:  Maybe Evt -> Model -> Model
>>> maybeUpdateModel evtOpt model =
>>>   case evtOpt of
>>> Nothing ->
>>>   model
>>>
>>> Just evt ->
>>>   updateModel evt model
>>>
>>> update : Msg -> Model -> (Model, Cmd Msg)
>>> update msg model =
>>>   case msg of
>>> Action act ->
>>>   let
>>> (eventNow, command) = doSideEffects act model
>>>   in
>>> (maybeUpdateModel eventNow model, Cmd.map Evt command)
>>>
>>> Event evt ->
>>>   (updateModel evt model, Cmd.none)
>>>
>>> So this should apply an event immediately if one is needed for the 
>>> action. But it still keeps the model updating events separate.
>>>
>>> These immediate events would be seen by a userland event-store 
>>> implementation (which is underneath updateModel), but I bet the TTD 
>>> wouldn't see it since it doesn't come from Elm.
>>>
>>> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:

 So you really are wanting to hard device events into two different 
 ones, those that can *only* alter the model, and those that can *only* 
 send 
 commands (which may call ones that alter the model).  Unsure if it might 
 actually happen but might have to take into account possible race 
 conditions for if other messages appear before your other expected ones 
 are 
 processed through?  Easier to do that atomically all at once?


 On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>
> doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
Isn't `doSideEffects` basically just the current `update` function though? 
 Except it is returning a list of changes (via message) to perform to a 
model instead of doing it in-place?  What is this saving precisely?



On Thursday, August 11, 2016 at 4:05:57 PM UTC-6, Kasey Speakman wrote:
>
> Actually, I'd probably use a List instead of Maybe on the immediately 
> returned event(s).
>
> doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
> doSideEffects act model = 
>   case act of
> UpdateCustomer customer ->
>   ( [ CustomerUpdateRequested ]
>   , callServerWithCustomer customer
>   )
>
> ...
>
> updateModel : Evt -> Model -> Model
> ... -- implementation as previous
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>   case msg of
> Action act ->
>   let
> (events, command) = doSideEffects act model
>   in
> (List.foldr updateModel model events, Cmd.map Evt command)
>
> Event evt ->
>   (updateModel evt model, Cmd.none)
>
>
>
> On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:
>>
>> Yes, that was the goal. That way the UI state is utterly deterministic / 
>> reproducible in isolation of all outside services.
>>
>> That's a good point on the race conditions. I only use Cmd.batch because 
>> it's the facility that came to mind. (I'm still getting acquainted with 
>> Elm.) I don't know if Cmd.batch makes any ordering guarantee.
>>
>> If not we'd be more or less back to square one. Abuse `update` to do both 
>> things.
>>
>> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
>> doSideEffects act model =
>>   case act of
>> UpdateCustomer customer ->
>>   (Just CustomerUpdateRequested, callServerWithCustomer customer)
>>
>> ...
>>
>> updateModel: Evt -> Model -> Model
>> ... -- implementation as previous
>>
>> maybeUpdateModel:  Maybe Evt -> Model -> Model
>> maybeUpdateModel evtOpt model =
>>   case evtOpt of
>> Nothing ->
>>   model
>>
>> Just evt ->
>>   updateModel evt model
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Action act ->
>>   let
>> (eventNow, command) = doSideEffects act model
>>   in
>> (maybeUpdateModel eventNow model, Cmd.map Evt command)
>>
>> Event evt ->
>>   (updateModel evt model, Cmd.none)
>>
>> So this should apply an event immediately if one is needed for the 
>> action. But it still keeps the model updating events separate.
>>
>> These immediate events would be seen by a userland event-store 
>> implementation (which is underneath updateModel), but I bet the TTD 
>> wouldn't see it since it doesn't come from Elm.
>>
>> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>>>
>>> So you really are wanting to hard device events into two different ones, 
>>> those that can *only* alter the model, and those that can *only* send 
>>> commands (which may call ones that alter the model).  Unsure if it might 
>>> actually happen but might have to take into account possible race 
>>> conditions for if other messages appear before your other expected ones are 
>>> processed through?  Easier to do that atomically all at once?
>>>
>>>
>>> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:

 doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Actually, I'd probably use a List instead of Maybe on the immediately 
returned event(s).

doSideEffects : Act -> Model -> (List Evt, Cmd Evt)
doSideEffects act model = 
  case act of
UpdateCustomer customer ->
  ( [ CustomerUpdateRequested ]
  , callServerWithCustomer customer
  )

...

updateModel : Evt -> Model -> Model
... -- implementation as previous

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Action act ->
  let
(events, command) = doSideEffects act model
  in
(List.foldr updateModel model events, Cmd.map Evt command)

Event evt ->
  (updateModel evt model, Cmd.none)



On Thursday, August 11, 2016 at 4:26:03 PM UTC-5, Kasey Speakman wrote:
>
> Yes, that was the goal. That way the UI state is utterly deterministic / 
> reproducible in isolation of all outside services.
>
> That's a good point on the race conditions. I only use Cmd.batch because 
> it's the facility that came to mind. (I'm still getting acquainted with 
> Elm.) I don't know if Cmd.batch makes any ordering guarantee.
>
> If not we'd be more or less back to square one. Abuse `update` to do both 
> things.
>
> doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
> doSideEffects act model =
>   case act of
> UpdateCustomer customer ->
>   (Just CustomerUpdateRequested, callServerWithCustomer customer)
>
> ...
>
> updateModel: Evt -> Model -> Model
> ... -- implementation as previous
>
> maybeUpdateModel:  Maybe Evt -> Model -> Model
> maybeUpdateModel evtOpt model =
>   case evtOpt of
> Nothing ->
>   model
>
> Just evt ->
>   updateModel evt model
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>   case msg of
> Action act ->
>   let
> (eventNow, command) = doSideEffects act model
>   in
> (maybeUpdateModel eventNow model, Cmd.map Evt command)
>
> Event evt ->
>   (updateModel evt model, Cmd.none)
>
> So this should apply an event immediately if one is needed for the action. 
> But it still keeps the model updating events separate.
>
> These immediate events would be seen by a userland event-store 
> implementation (which is underneath updateModel), but I bet the TTD 
> wouldn't see it since it doesn't come from Elm.
>
> On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>>
>> So you really are wanting to hard device events into two different ones, 
>> those that can *only* alter the model, and those that can *only* send 
>> commands (which may call ones that alter the model).  Unsure if it might 
>> actually happen but might have to take into account possible race 
>> conditions for if other messages appear before your other expected ones are 
>> processed through?  Easier to do that atomically all at once?
>>
>>
>> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>>>
>>> doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Yes, that was the goal. That way the UI state is utterly deterministic / 
reproducible in isolation of all outside services.

That's a good point on the race conditions. I only use Cmd.batch because 
it's the facility that came to mind. (I'm still getting acquainted with 
Elm.) I don't know if Cmd.batch makes any ordering guarantee.

If not we'd be more or less back to square one. Abuse `update` to do both 
things.

doSideEffects: Act -> Model -> (Maybe Evt, Cmd Evt)
doSideEffects act model =
  case act of
UpdateCustomer customer ->
  (Just CustomerUpdateRequested, callServerWithCustomer customer)

...

updateModel: Evt -> Model -> Model
... -- implementation as previous

maybeUpdateModel:  Maybe Evt -> Model -> Model
maybeUpdateModel evtOpt model =
  case evtOpt of
Nothing ->
  model

Just evt ->
  updateModel evt model

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Action act ->
  let
(eventNow, command) = doSideEffects act model
  in
(maybeUpdateModel eventNow model, Cmd.map Evt command)

Event evt ->
  (updateModel evt model, Cmd.none)

So this should apply an event immediately if one is needed for the action. 
But it still keeps the model updating events separate.

These immediate events would be seen by a userland event-store 
implementation (which is underneath updateModel), but I bet the TTD 
wouldn't see it since it doesn't come from Elm.

On Thursday, August 11, 2016 at 3:43:36 PM UTC-5, OvermindDL1 wrote:
>
> So you really are wanting to hard device events into two different ones, 
> those that can *only* alter the model, and those that can *only* send 
> commands (which may call ones that alter the model).  Unsure if it might 
> actually happen but might have to take into account possible race 
> conditions for if other messages appear before your other expected ones are 
> processed through?  Easier to do that atomically all at once?
>
>
> On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>>
>> doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
So you really are wanting to hard device events into two different ones, 
those that can *only* alter the model, and those that can *only* send 
commands (which may call ones that alter the model).  Unsure if it might 
actually happen but might have to take into account possible race 
conditions for if other messages appear before your other expected ones are 
processed through?  Easier to do that atomically all at once?


On Thursday, August 11, 2016 at 2:25:22 PM UTC-6, Kasey Speakman wrote:
>
> doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
doSideEffects above would also have to map Cmd Evt to Cmd 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.


[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
My mistake, SubmitCustomerChanges was supposed to be UpdateCustomer above.

On Thursday, August 11, 2016 at 3:16:12 PM UTC-5, Kasey Speakman wrote:
>
> Oh! What I was doing in my examples was pretending there was a version of 
> Elm that natively supported `command` and `update` methods instead of just 
> `update`. I was exploring what that could look like, how it would affect 
> things.
>
> I don't have a complete example in mind. The original post was more to get 
> the idea out there and discuss it.
>
> So, I suppose I could also explore putting the command/event separation 
> into practice as subsets of Msg which should work with non-imaginary Elm.
>
> type Act
>   = UpdateCustomer customer
>   | ... -- another command
>
> type Evt
>   = NameChanged name
>   | CustomerUpdateRequested
>   | CustomerUpdateFailed err
>   | CustomerUpdateSucceeded
>
> type Msg
>   = Action act
>   | Event evt
>
> doSideEffects: Act -> Model -> Cmd Evt
> doSideEffects act model =
>   case act of
> SubmitCustomerChanges customer ->
>   Cmd.batch
> [ Cmd.fromEvt CustomerUpdateRequested
> , callServerWithCustomer customer -- or model.Customer?
> ]
>
> ...
>
> updateModel: Evt -> Model -> Model
> ... -- implementation as previous
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>   case msg of
> Action act ->
>   (model, doSideEffects act model)
>
> Event evt ->
>   (updateModel evt model, Cmd.none)
>
> Apologize for errors... writing code in this groups editor.
>
> Anyway, this is the other choice I mentioned where you could let the view 
> send either a command or event. This could prevent redundant "commands", 
> example: `onInput`s which only change the model could issue an event 
> directly instead of a command first. I thought this would require more 
> discipline to use, but now that I see it, I think using "commands" (Action 
> above) and "events" appropriately is enforced by `update`. If you want an 
> event when an action happens, you could use a Cmd.batch (as in 
> CustomerUpdateRequested above). That enforces model updates being separate 
> messages from effects.
>
> For event-sourcing, you could replay only the `Event`s in complete 
> isolation of the outside world to arrive at an interesting UI state. For 
> example, an incorrect state that was bug reported.
>
> On Thursday, August 11, 2016 at 2:21:42 PM UTC-5, Kasey Speakman wrote:
>>
>> I'm not sure I like it either. Seems like a lot of UI commands would just 
>> be auto-converted to events by `command`.
>>
>> However, in your example, I'm not sure what your filter code is about (my 
>> ignorance). If I am understanding it right, it's filling in for the case 
>> when you need to respond to an event and issue another command. This also 
>> seems like a separate concern from what I mentioned.
>>
>> On Thursday, August 11, 2016 at 1:53:15 PM UTC-5, OvermindDL1 wrote:
>>>
>>> Yeah I was playing with the idea for more message types though still not 
>>> convinced yet.  Let's go hog-wild for a second to see how it would look 
>>> with a fairly major overhaul and multiple message types though:
>>> ```elm
>>>
>>> {-| Msg is used for global message dispatching, handled only by the 
>>> `filters` callback -}type Msg
>>>   = ConnectTo Int
>>>   | RoomConnected Int
>>>   | ReceivedMessage String
>>>   | MsgOnInput String
>>>   | SendMsgDo
>>> type CmdMsg
>>>   = FocusInputBox
>>>   | ScrollInputBox
>>>   | ConnectToRoom Int
>>>   | SendMsgToRoom String
>>> type UpdMsg
>>>   = JoinedRoom
>>>   | MsgTyped String
>>>   | MsgSent
>>> type alias Model =
>>>   { uid : Int
>>>   , msg : String
>>>   , msgs : List String
>>>   }
>>> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
>>> filters : Msg -> Model -> States Model Msgfilters msg model =
>>>   case msg of
>>> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
>>> rid)
>>> RoomConnected uid ->
>>>   States.enableAll
>>>   |> States.sendCommand FocusInputBox
>>>   |> States.sendCommand ScrollInputBox
>>>   |> States.sendUpdate JoinedRoom
>>> ReceivedMessage msg -> States.enableAll
>>> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
>>> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
>>> model.msg)
>>> update : UpdMsg -> Model -> Modelupdate msg model =
>>>   case msg of
>>> JoinedRoom -> { model | msg="", msgs=[] }
>>> MsgTyped msg -> { model | msg=msg }
>>> MsgSent ->{ model | msg="" }
>>> command : Msg -> Model -> Cmd Msgcommand msg model =
>>>   case msg of
>>> FocusInputBox -> focusMessageInput
>>> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
>>> ".messenger-mesglist"
>>> ConnectToRoom rid -> connectToRoom rid
>>> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>>>
>>> ```
>>>
>>> Eh I am not sure I like it, at all actually.  It basically converts the 
>>> usual helper functions into in-li

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Oh! What I was doing in my examples was pretending there was a version of 
Elm that natively supported `command` and `update` methods instead of just 
`update`. I was exploring what that could look like, how it would affect 
things.

I don't have a complete example in mind. The original post was more to get 
the idea out there and discuss it.

So, I suppose I could also explore putting the command/event separation 
into practice as subsets of Msg which should work with non-imaginary Elm.

type Act
  = UpdateCustomer customer
  | ... -- another command

type Evt
  = NameChanged name
  | CustomerUpdateRequested
  | CustomerUpdateFailed err
  | CustomerUpdateSucceeded

type Msg
  = Action act
  | Event evt

doSideEffects: Act -> Model -> Cmd Evt
doSideEffects act model =
  case act of
SubmitCustomerChanges customer ->
  Cmd.batch
[ Cmd.fromEvt CustomerUpdateRequested
, callServerWithCustomer customer -- or model.Customer?
]

...

updateModel: Evt -> Model -> Model
... -- implementation as previous

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Action act ->
  (model, doSideEffects act model)

Event evt ->
  (updateModel evt model, Cmd.none)

Apologize for errors... writing code in this groups editor.

Anyway, this is the other choice I mentioned where you could let the view 
send either a command or event. This could prevent redundant "commands", 
example: `onInput`s which only change the model could issue an event 
directly instead of a command first. I thought this would require more 
discipline to use, but now that I see it, I think using "commands" (Action 
above) and "events" appropriately is enforced by `update`. If you want an 
event when an action happens, you could use a Cmd.batch (as in 
CustomerUpdateRequested above). That enforces model updates being separate 
messages from effects.

For event-sourcing, you could replay only the `Event`s in complete 
isolation of the outside world to arrive at an interesting UI state. For 
example, an incorrect state that was bug reported.

On Thursday, August 11, 2016 at 2:21:42 PM UTC-5, Kasey Speakman wrote:
>
> I'm not sure I like it either. Seems like a lot of UI commands would just 
> be auto-converted to events by `command`.
>
> However, in your example, I'm not sure what your filter code is about (my 
> ignorance). If I am understanding it right, it's filling in for the case 
> when you need to respond to an event and issue another command. This also 
> seems like a separate concern from what I mentioned.
>
> On Thursday, August 11, 2016 at 1:53:15 PM UTC-5, OvermindDL1 wrote:
>>
>> Yeah I was playing with the idea for more message types though still not 
>> convinced yet.  Let's go hog-wild for a second to see how it would look 
>> with a fairly major overhaul and multiple message types though:
>> ```elm
>>
>> {-| Msg is used for global message dispatching, handled only by the 
>> `filters` callback -}type Msg
>>   = ConnectTo Int
>>   | RoomConnected Int
>>   | ReceivedMessage String
>>   | MsgOnInput String
>>   | SendMsgDo
>> type CmdMsg
>>   = FocusInputBox
>>   | ScrollInputBox
>>   | ConnectToRoom Int
>>   | SendMsgToRoom String
>> type UpdMsg
>>   = JoinedRoom
>>   | MsgTyped String
>>   | MsgSent
>> type alias Model =
>>   { uid : Int
>>   , msg : String
>>   , msgs : List String
>>   }
>> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
>> filters : Msg -> Model -> States Model Msgfilters msg model =
>>   case msg of
>> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
>> rid)
>> RoomConnected uid ->
>>   States.enableAll
>>   |> States.sendCommand FocusInputBox
>>   |> States.sendCommand ScrollInputBox
>>   |> States.sendUpdate JoinedRoom
>> ReceivedMessage msg -> States.enableAll
>> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
>> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
>> model.msg)
>> update : UpdMsg -> Model -> Modelupdate msg model =
>>   case msg of
>> JoinedRoom -> { model | msg="", msgs=[] }
>> MsgTyped msg -> { model | msg=msg }
>> MsgSent ->{ model | msg="" }
>> command : Msg -> Model -> Cmd Msgcommand msg model =
>>   case msg of
>> FocusInputBox -> focusMessageInput
>> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
>> ".messenger-mesglist"
>> ConnectToRoom rid -> connectToRoom rid
>> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>>
>> ```
>>
>> Eh I am not sure I like it, at all actually.  It basically converts the 
>> usual helper functions into in-line in the case branches.  It separates the 
>> commands and update messages out, however all the original logic is now in 
>> filter, which is basically just redistributing things (maybe it should be 
>> called `router` at this point) and is growing larger then its purpose was 
>> meant.  Not sure of a good API yet...
>>
>>
>> On Th

Re: [elm-discuss] What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Wouter In t Velt
my steepest learning curve in Elm is getting to grips with what to put where
- no view stuff in the model
- where in the hierarchy to put which data (the sortable table was a real 
eye-opener)
- when to give something state (i.e. an update function and own Msg type)

And most of all: how to structure messages and communication between 
components/ elements.
Look at various good posts on child to parent communication (kudos to Brian 
Hicks's excellent post on the subject).

-- 
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] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
Can you supply a complete example of what you want it to look like 
(excepting view, we don't care about view right now).?


On Thursday, August 11, 2016 at 1:25:38 PM UTC-6, OvermindDL1 wrote:
>
> In this case it is just filling in for 'something' that can dispatch some 
> messages to `update` and dispatch commands to `command`.  I'm not sure how 
> to dispatch those without some dispatcher that is already acting like the 
> existing update...
>
>
> On Thursday, August 11, 2016 at 1:21:42 PM UTC-6, Kasey Speakman wrote:
>>
>> I'm not sure I like it either. Seems like a lot of UI commands would just 
>> be auto-converted to events by `command`.
>>
>> However, in your example, I'm not sure what your filter code is about (my 
>> ignorance). If I am understanding it right, it's filling in for the case 
>> when you need to respond to an event and issue another command. This also 
>> seems like a separate concern from what I mentioned.
>>
>> On Thursday, August 11, 2016 at 1:53:15 PM UTC-5, OvermindDL1 wrote:
>>>
>>> Yeah I was playing with the idea for more message types though still not 
>>> convinced yet.  Let's go hog-wild for a second to see how it would look 
>>> with a fairly major overhaul and multiple message types though:
>>> ```elm
>>>
>>> {-| Msg is used for global message dispatching, handled only by the 
>>> `filters` callback -}type Msg
>>>   = ConnectTo Int
>>>   | RoomConnected Int
>>>   | ReceivedMessage String
>>>   | MsgOnInput String
>>>   | SendMsgDo
>>> type CmdMsg
>>>   = FocusInputBox
>>>   | ScrollInputBox
>>>   | ConnectToRoom Int
>>>   | SendMsgToRoom String
>>> type UpdMsg
>>>   = JoinedRoom
>>>   | MsgTyped String
>>>   | MsgSent
>>> type alias Model =
>>>   { uid : Int
>>>   , msg : String
>>>   , msgs : List String
>>>   }
>>> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
>>> filters : Msg -> Model -> States Model Msgfilters msg model =
>>>   case msg of
>>> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
>>> rid)
>>> RoomConnected uid ->
>>>   States.enableAll
>>>   |> States.sendCommand FocusInputBox
>>>   |> States.sendCommand ScrollInputBox
>>>   |> States.sendUpdate JoinedRoom
>>> ReceivedMessage msg -> States.enableAll
>>> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
>>> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
>>> model.msg)
>>> update : UpdMsg -> Model -> Modelupdate msg model =
>>>   case msg of
>>> JoinedRoom -> { model | msg="", msgs=[] }
>>> MsgTyped msg -> { model | msg=msg }
>>> MsgSent ->{ model | msg="" }
>>> command : Msg -> Model -> Cmd Msgcommand msg model =
>>>   case msg of
>>> FocusInputBox -> focusMessageInput
>>> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
>>> ".messenger-mesglist"
>>> ConnectToRoom rid -> connectToRoom rid
>>> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>>>
>>> ```
>>>
>>> Eh I am not sure I like it, at all actually.  It basically converts the 
>>> usual helper functions into in-line in the case branches.  It separates the 
>>> commands and update messages out, however all the original logic is now in 
>>> filter, which is basically just redistributing things (maybe it should be 
>>> called `router` at this point) and is growing larger then its purpose was 
>>> meant.  Not sure of a good API yet...
>>>
>>>
>>> On Thursday, August 11, 2016 at 12:32:44 PM UTC-6, Kasey Speakman wrote:

 I do like the signatures you mentioned:

 `update : Msg -> Model -> Model`
 `command: Msg -> Model -> Cmd Msg`

 However at that point, it no longer makes sense to use the same 
 messages for effects and model updates. For example:

 `update: Evt -> Model -> Model`
 `command: Act -> Model -> Cmd Evt`

 Here, using Act for commands since Cmd is already taken. Evt for events 
 (facts which have occurred).

 The question then becomes how `view` would be affected. Html Msg 
 doesn't work there. If you did Html Act, then there is some boilerplate 
 for 
 actions that don't have effects:

 ```
 -- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
 command : Act -> Model -> Cmd Evt
 command act model =
   case act of
 ChangeName name -> 
   Cmd.fromEvt <| NameChanged name

 SubmitCustomerChanges customer ->
   Cmd.batch
 [ Cmd.fromEvt <| CustomerChangesSubmitted
 , callServerWithCustomer customer -- or model.Customer?
 ]
 ```

 An alternative is to allow Html to produce either Act or Evt. But that 
 feels wrong. It would be too easy to try to use only one or the other for 
 all the work.

 On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:
>
> It was just something that bugged me when I first saw it in the 
> examples, and I just came to the realizat

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
In this case it is just filling in for 'something' that can dispatch some 
messages to `update` and dispatch commands to `command`.  I'm not sure how 
to dispatch those without some dispatcher that is already acting like the 
existing update...


On Thursday, August 11, 2016 at 1:21:42 PM UTC-6, Kasey Speakman wrote:
>
> I'm not sure I like it either. Seems like a lot of UI commands would just 
> be auto-converted to events by `command`.
>
> However, in your example, I'm not sure what your filter code is about (my 
> ignorance). If I am understanding it right, it's filling in for the case 
> when you need to respond to an event and issue another command. This also 
> seems like a separate concern from what I mentioned.
>
> On Thursday, August 11, 2016 at 1:53:15 PM UTC-5, OvermindDL1 wrote:
>>
>> Yeah I was playing with the idea for more message types though still not 
>> convinced yet.  Let's go hog-wild for a second to see how it would look 
>> with a fairly major overhaul and multiple message types though:
>> ```elm
>>
>> {-| Msg is used for global message dispatching, handled only by the 
>> `filters` callback -}type Msg
>>   = ConnectTo Int
>>   | RoomConnected Int
>>   | ReceivedMessage String
>>   | MsgOnInput String
>>   | SendMsgDo
>> type CmdMsg
>>   = FocusInputBox
>>   | ScrollInputBox
>>   | ConnectToRoom Int
>>   | SendMsgToRoom String
>> type UpdMsg
>>   = JoinedRoom
>>   | MsgTyped String
>>   | MsgSent
>> type alias Model =
>>   { uid : Int
>>   , msg : String
>>   , msgs : List String
>>   }
>> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
>> filters : Msg -> Model -> States Model Msgfilters msg model =
>>   case msg of
>> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
>> rid)
>> RoomConnected uid ->
>>   States.enableAll
>>   |> States.sendCommand FocusInputBox
>>   |> States.sendCommand ScrollInputBox
>>   |> States.sendUpdate JoinedRoom
>> ReceivedMessage msg -> States.enableAll
>> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
>> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
>> model.msg)
>> update : UpdMsg -> Model -> Modelupdate msg model =
>>   case msg of
>> JoinedRoom -> { model | msg="", msgs=[] }
>> MsgTyped msg -> { model | msg=msg }
>> MsgSent ->{ model | msg="" }
>> command : Msg -> Model -> Cmd Msgcommand msg model =
>>   case msg of
>> FocusInputBox -> focusMessageInput
>> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
>> ".messenger-mesglist"
>> ConnectToRoom rid -> connectToRoom rid
>> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>>
>> ```
>>
>> Eh I am not sure I like it, at all actually.  It basically converts the 
>> usual helper functions into in-line in the case branches.  It separates the 
>> commands and update messages out, however all the original logic is now in 
>> filter, which is basically just redistributing things (maybe it should be 
>> called `router` at this point) and is growing larger then its purpose was 
>> meant.  Not sure of a good API yet...
>>
>>
>> On Thursday, August 11, 2016 at 12:32:44 PM UTC-6, Kasey Speakman wrote:
>>>
>>> I do like the signatures you mentioned:
>>>
>>> `update : Msg -> Model -> Model`
>>> `command: Msg -> Model -> Cmd Msg`
>>>
>>> However at that point, it no longer makes sense to use the same messages 
>>> for effects and model updates. For example:
>>>
>>> `update: Evt -> Model -> Model`
>>> `command: Act -> Model -> Cmd Evt`
>>>
>>> Here, using Act for commands since Cmd is already taken. Evt for events 
>>> (facts which have occurred).
>>>
>>> The question then becomes how `view` would be affected. Html Msg doesn't 
>>> work there. If you did Html Act, then there is some boilerplate for actions 
>>> that don't have effects:
>>>
>>> ```
>>> -- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
>>> command : Act -> Model -> Cmd Evt
>>> command act model =
>>>   case act of
>>> ChangeName name -> 
>>>   Cmd.fromEvt <| NameChanged name
>>>
>>> SubmitCustomerChanges customer ->
>>>   Cmd.batch
>>> [ Cmd.fromEvt <| CustomerChangesSubmitted
>>> , callServerWithCustomer customer -- or model.Customer?
>>> ]
>>> ```
>>>
>>> An alternative is to allow Html to produce either Act or Evt. But that 
>>> feels wrong. It would be too easy to try to use only one or the other for 
>>> all the work.
>>>
>>> On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:

 It was just something that bugged me when I first saw it in the 
 examples, and I just came to the realization of why. And I am wondering 
 out 
 loud what it look like if they were separate things.

 In your example case, you could make a 3rd command that did the issued 
 a new message InfoConnectIdAssigned to separate the model bit out. The 
 tradeoff is isolation of model changes vs increased boilerplate (is

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
I'm not sure I like it either. Seems like a lot of UI commands would just 
be auto-converted to events by `command`.

However, in your example, I'm not sure what your filter code is about (my 
ignorance). If I am understanding it right, it's filling in for the case 
when you need to respond to an event and issue another command. This also 
seems like a separate concern from what I mentioned.

On Thursday, August 11, 2016 at 1:53:15 PM UTC-5, OvermindDL1 wrote:
>
> Yeah I was playing with the idea for more message types though still not 
> convinced yet.  Let's go hog-wild for a second to see how it would look 
> with a fairly major overhaul and multiple message types though:
> ```elm
>
> {-| Msg is used for global message dispatching, handled only by the `filters` 
> callback -}type Msg
>   = ConnectTo Int
>   | RoomConnected Int
>   | ReceivedMessage String
>   | MsgOnInput String
>   | SendMsgDo
> type CmdMsg
>   = FocusInputBox
>   | ScrollInputBox
>   | ConnectToRoom Int
>   | SendMsgToRoom String
> type UpdMsg
>   = JoinedRoom
>   | MsgTyped String
>   | MsgSent
> type alias Model =
>   { uid : Int
>   , msg : String
>   , msgs : List String
>   }
> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
> filters : Msg -> Model -> States Model Msgfilters msg model =
>   case msg of
> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
> rid)
> RoomConnected uid ->
>   States.enableAll
>   |> States.sendCommand FocusInputBox
>   |> States.sendCommand ScrollInputBox
>   |> States.sendUpdate JoinedRoom
> ReceivedMessage msg -> States.enableAll
> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
> model.msg)
> update : UpdMsg -> Model -> Modelupdate msg model =
>   case msg of
> JoinedRoom -> { model | msg="", msgs=[] }
> MsgTyped msg -> { model | msg=msg }
> MsgSent ->{ model | msg="" }
> command : Msg -> Model -> Cmd Msgcommand msg model =
>   case msg of
> FocusInputBox -> focusMessageInput
> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
> ".messenger-mesglist"
> ConnectToRoom rid -> connectToRoom rid
> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>
> ```
>
> Eh I am not sure I like it, at all actually.  It basically converts the 
> usual helper functions into in-line in the case branches.  It separates the 
> commands and update messages out, however all the original logic is now in 
> filter, which is basically just redistributing things (maybe it should be 
> called `router` at this point) and is growing larger then its purpose was 
> meant.  Not sure of a good API yet...
>
>
> On Thursday, August 11, 2016 at 12:32:44 PM UTC-6, Kasey Speakman wrote:
>>
>> I do like the signatures you mentioned:
>>
>> `update : Msg -> Model -> Model`
>> `command: Msg -> Model -> Cmd Msg`
>>
>> However at that point, it no longer makes sense to use the same messages 
>> for effects and model updates. For example:
>>
>> `update: Evt -> Model -> Model`
>> `command: Act -> Model -> Cmd Evt`
>>
>> Here, using Act for commands since Cmd is already taken. Evt for events 
>> (facts which have occurred).
>>
>> The question then becomes how `view` would be affected. Html Msg doesn't 
>> work there. If you did Html Act, then there is some boilerplate for actions 
>> that don't have effects:
>>
>> ```
>> -- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
>> command : Act -> Model -> Cmd Evt
>> command act model =
>>   case act of
>> ChangeName name -> 
>>   Cmd.fromEvt <| NameChanged name
>>
>> SubmitCustomerChanges customer ->
>>   Cmd.batch
>> [ Cmd.fromEvt <| CustomerChangesSubmitted
>> , callServerWithCustomer customer -- or model.Customer?
>> ]
>> ```
>>
>> An alternative is to allow Html to produce either Act or Evt. But that 
>> feels wrong. It would be too easy to try to use only one or the other for 
>> all the work.
>>
>> On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:
>>>
>>> It was just something that bugged me when I first saw it in the 
>>> examples, and I just came to the realization of why. And I am wondering out 
>>> loud what it look like if they were separate things.
>>>
>>> In your example case, you could make a 3rd command that did the issued a 
>>> new message InfoConnectIdAssigned to separate the model bit out. The 
>>> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
>>> no-effect command). I think a shortcut method could be in order like 
>>> Cmd.none, but something like Cmd.fromMsg.
>>>
>>> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:

 I guess what you are proposing is separating a Message into a 
 'commands' and 'update' callbacks?  That could work well too...  I could 
 add that as an option to my ProgramEx testing library (where I test with 
 extra callba

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
Yeah the more I look at it this specific example the more I dislike it.  It 
is basically doing the model and command updates in the filters callback, 
but instead of 'just doing it' it instead dispatches messages that do it, 
gaining really nothing in readability or code size.


On Thursday, August 11, 2016 at 12:53:15 PM UTC-6, OvermindDL1 wrote:
>
> Yeah I was playing with the idea for more message types though still not 
> convinced yet.  Let's go hog-wild for a second to see how it would look 
> with a fairly major overhaul and multiple message types though:
> ```elm
>
> {-| Msg is used for global message dispatching, handled only by the `filters` 
> callback -}type Msg
>   = ConnectTo Int
>   | RoomConnected Int
>   | ReceivedMessage String
>   | MsgOnInput String
>   | SendMsgDo
> type CmdMsg
>   = FocusInputBox
>   | ScrollInputBox
>   | ConnectToRoom Int
>   | SendMsgToRoom String
> type UpdMsg
>   = JoinedRoom
>   | MsgTyped String
>   | MsgSent
> type alias Model =
>   { uid : Int
>   , msg : String
>   , msgs : List String
>   }
> init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
> filters : Msg -> Model -> States Model Msgfilters msg model =
>   case msg of
> ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom 
> rid)
> RoomConnected uid ->
>   States.enableAll
>   |> States.sendCommand FocusInputBox
>   |> States.sendCommand ScrollInputBox
>   |> States.sendUpdate JoinedRoom
> ReceivedMessage msg -> States.enableAll
> MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
> SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
> model.msg)
> update : UpdMsg -> Model -> Modelupdate msg model =
>   case msg of
> JoinedRoom -> { model | msg="", msgs=[] }
> MsgTyped msg -> { model | msg=msg }
> MsgSent ->{ model | msg="" }
> command : Msg -> Model -> Cmd Msgcommand msg model =
>   case msg of
> FocusInputBox -> focusMessageInput
> ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
> ".messenger-mesglist"
> ConnectToRoom rid -> connectToRoom rid
> SendMsgToRoom msg -> sendMsgToConnectedRoom msg
>
> ```
>
> Eh I am not sure I like it, at all actually.  It basically converts the 
> usual helper functions into in-line in the case branches.  It separates the 
> commands and update messages out, however all the original logic is now in 
> filter, which is basically just redistributing things (maybe it should be 
> called `router` at this point) and is growing larger then its purpose was 
> meant.  Not sure of a good API yet...
>
>
> On Thursday, August 11, 2016 at 12:32:44 PM UTC-6, Kasey Speakman wrote:
>>
>> I do like the signatures you mentioned:
>>
>> `update : Msg -> Model -> Model`
>> `command: Msg -> Model -> Cmd Msg`
>>
>> However at that point, it no longer makes sense to use the same messages 
>> for effects and model updates. For example:
>>
>> `update: Evt -> Model -> Model`
>> `command: Act -> Model -> Cmd Evt`
>>
>> Here, using Act for commands since Cmd is already taken. Evt for events 
>> (facts which have occurred).
>>
>> The question then becomes how `view` would be affected. Html Msg doesn't 
>> work there. If you did Html Act, then there is some boilerplate for actions 
>> that don't have effects:
>>
>> ```
>> -- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
>> command : Act -> Model -> Cmd Evt
>> command act model =
>>   case act of
>> ChangeName name -> 
>>   Cmd.fromEvt <| NameChanged name
>>
>> SubmitCustomerChanges customer ->
>>   Cmd.batch
>> [ Cmd.fromEvt <| CustomerChangesSubmitted
>> , callServerWithCustomer customer -- or model.Customer?
>> ]
>> ```
>>
>> An alternative is to allow Html to produce either Act or Evt. But that 
>> feels wrong. It would be too easy to try to use only one or the other for 
>> all the work.
>>
>> On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:
>>>
>>> It was just something that bugged me when I first saw it in the 
>>> examples, and I just came to the realization of why. And I am wondering out 
>>> loud what it look like if they were separate things.
>>>
>>> In your example case, you could make a 3rd command that did the issued a 
>>> new message InfoConnectIdAssigned to separate the model bit out. The 
>>> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
>>> no-effect command). I think a shortcut method could be in order like 
>>> Cmd.none, but something like Cmd.fromMsg.
>>>
>>> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:

 I guess what you are proposing is separating a Message into a 
 'commands' and 'update' callbacks?  That could work well too...  I could 
 add that as an option to my ProgramEx testing library (where I test with 
 extra callbacks) if you want to play around with it?  Do you propose that 
 `update` would be `Msg -> Model -> Model` and 

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
Yeah I was playing with the idea for more message types though still not 
convinced yet.  Let's go hog-wild for a second to see how it would look 
with a fairly major overhaul and multiple message types though:
```elm

{-| Msg is used for global message dispatching, handled only by the `filters` 
callback -}type Msg
  = ConnectTo Int
  | RoomConnected Int
  | ReceivedMessage String
  | MsgOnInput String
  | SendMsgDo
type CmdMsg
  = FocusInputBox
  | ScrollInputBox
  | ConnectToRoom Int
  | SendMsgToRoom String
type UpdMsg
  = JoinedRoom
  | MsgTyped String
  | MsgSent
type alias Model =
  { uid : Int
  , msg : String
  , msgs : List String
  }
init : ( Model, Cmd Msg )init = ( Model 0 "" [], connectToServer )
filters : Msg -> Model -> States Model Msgfilters msg model =
  case msg of
ConnectTo rid -> States.enableAll |> States.sendCommand (ConnectToRoom rid)
RoomConnected uid ->
  States.enableAll
  |> States.sendCommand FocusInputBox
  |> States.sendCommand ScrollInputBox
  |> States.sendUpdate JoinedRoom
ReceivedMessage msg -> States.enableAll
MsgOnInput msg -> States.enableAll |> States.sendUpdate (MsgTyped msg)
SendMsgDo -> States.enableAll |> States.sendCommand (SendMsgToRoom 
model.msg)
update : UpdMsg -> Model -> Modelupdate msg model =
  case msg of
JoinedRoom -> { model | msg="", msgs=[] }
MsgTyped msg -> { model | msg=msg }
MsgSent ->{ model | msg="" }
command : Msg -> Model -> Cmd Msgcommand msg model =
  case msg of
FocusInputBox -> focusMessageInput
ScrollInputBox -> scrollScrollable Helpers Scrollable_Bottom 
".messenger-mesglist"
ConnectToRoom rid -> connectToRoom rid
SendMsgToRoom msg -> sendMsgToConnectedRoom msg

```

Eh I am not sure I like it, at all actually.  It basically converts the 
usual helper functions into in-line in the case branches.  It separates the 
commands and update messages out, however all the original logic is now in 
filter, which is basically just redistributing things (maybe it should be 
called `router` at this point) and is growing larger then its purpose was 
meant.  Not sure of a good API yet...


On Thursday, August 11, 2016 at 12:32:44 PM UTC-6, Kasey Speakman wrote:
>
> I do like the signatures you mentioned:
>
> `update : Msg -> Model -> Model`
> `command: Msg -> Model -> Cmd Msg`
>
> However at that point, it no longer makes sense to use the same messages 
> for effects and model updates. For example:
>
> `update: Evt -> Model -> Model`
> `command: Act -> Model -> Cmd Evt`
>
> Here, using Act for commands since Cmd is already taken. Evt for events 
> (facts which have occurred).
>
> The question then becomes how `view` would be affected. Html Msg doesn't 
> work there. If you did Html Act, then there is some boilerplate for actions 
> that don't have effects:
>
> ```
> -- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
> command : Act -> Model -> Cmd Evt
> command act model =
>   case act of
> ChangeName name -> 
>   Cmd.fromEvt <| NameChanged name
>
> SubmitCustomerChanges customer ->
>   Cmd.batch
> [ Cmd.fromEvt <| CustomerChangesSubmitted
> , callServerWithCustomer customer -- or model.Customer?
> ]
> ```
>
> An alternative is to allow Html to produce either Act or Evt. But that 
> feels wrong. It would be too easy to try to use only one or the other for 
> all the work.
>
> On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:
>>
>> It was just something that bugged me when I first saw it in the examples, 
>> and I just came to the realization of why. And I am wondering out loud what 
>> it look like if they were separate things.
>>
>> In your example case, you could make a 3rd command that did the issued a 
>> new message InfoConnectIdAssigned to separate the model bit out. The 
>> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
>> no-effect command). I think a shortcut method could be in order like 
>> Cmd.none, but something like Cmd.fromMsg.
>>
>> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>>>
>>> I guess what you are proposing is separating a Message into a 'commands' 
>>> and 'update' callbacks?  That could work well too...  I could add that as 
>>> an option to my ProgramEx testing library (where I test with extra 
>>> callbacks) if you want to play around with it?  Do you propose that 
>>> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
>>> Model -> Cmd Msg, running in sequence of command before update?  I can see 
>>> a lot of them having a lot of duplicate code though, but I guess that could 
>>> be removed from my currently testing `filters` callback to clean up the 
>>> message into more pure stateful messages.  Though if I did that I really 
>>> think I would want to make two different message types, one for filters and 
>>> one for consuming, however that may make larger API changes than would be 
>>> easy...  What precisely wo

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Think we posted replies about the same time. For it to work, I think Msg 
alone would not suffice. There would have to be two message types.

On Thursday, August 11, 2016 at 1:37:06 PM UTC-5, OvermindDL1 wrote:
>
> So it seems that you would have something like a `commands` callback send 
> out commands, one of those would be a command just for sending messages to 
> `update` without sending the original message?  (Also, it is already easy 
> to make commands from messages although Cmd.fromMsg would be shorter).  So 
> you are thinking of something like:
> ```elm
>
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
> Something blah -> Cmd.batch
>   [ doSomething
>   , Cmd.fromMsg MyUpdateMsg blah
>   ]
> update : ChangeMsg -> Model -> Modelupdate msg model =
>   case msg of
> MyUpdateMsg blah = { model | blah = blah }
>
> ```
>
> I am unsure about making model changes be a command like that to be 
> honest.  I'd probably opt for something more like:
> ```elm
>
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
> Something blah -> Cmd.batch
>   [ doSomething
>   ]
> update : Msg -> Model -> Modelupdate msg model =
>   case msg of
> Something blah = { model | blah = blah }
>
> ```
> Where the commands happen first then the model update, however you will 
> often have to do the same calculations in both to figure out something when 
> a message causes both (as some of mine do), which is duplicating effort.
>
> Something that might work that I could see would be something like with 
> the filters callback I propose:
> ```elm
>
> filters : BaseMsg -> Model -> ( Msg, States Model Msg )filters msg model =
>   case msg of
> ReceivedAMsg blah ->
>   ( Something (blah+42), States.enableAll )
> commands : Msg -> Model -> Cmd Msgcommands msg model =
>   case msg of
> Something blah -> Cmd.batch
>   [ doSomething
>   ]
> update : Msg -> Model -> Modelupdate msg model =
>   case msg of
> Something blah = { model | blah = blah }
>
> ```
> But even that does the returning two things that you mention but in 
> filters, although I think they are inextricably tied together so they make 
> sense, maybe change `filters` to a different API like:
> ```elm
>
> filters : BaseMsg -> Model -> States Model Msgfilters msg model =
>   case msg of
> ReceivedAMsg blah -> States.enableAll |> States.sendMsg (Something 
> (blah+42))
>
> ```
> Although then you have to pass forward every single message manually, 
> which might not be a bad things all considered, but definitely more wordy 
> and not really any more clear.  Maybe make `BaseMsg` just be `Msg` again 
> and have States control whether the original message is overridden or not, 
> that seems more clear to me, if no override is specified for the message 
> then it just passes through the original.  I still do not think I like that 
> though.
>
> Cannot think that commands could be a one-off subscription either.
>
> Eh, I am not really sure, decoupling Commands from the Updates is going to 
> cause a lot of code duplication, which you could resolve via a filters 
> function but then you get a lot more Message types, which although would 
> make things clear, not sure of how it should follow out to the end there 
> yet...  Maybe if filters had a way to send out more messages than just one, 
> or different types of messages...
>
>
> On Thursday, August 11, 2016 at 12:03:47 PM UTC-6, Kasey Speakman wrote:
>>
>> It was just something that bugged me when I first saw it in the examples, 
>> and I just came to the realization of why. And I am wondering out loud what 
>> it look like if they were separate things.
>>
>> In your example case, you could make a 3rd command that did the issued a 
>> new message InfoConnectIdAssigned to separate the model bit out. The 
>> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
>> no-effect command). I think a shortcut method could be in order like 
>> Cmd.none, but something like Cmd.fromMsg.
>>
>> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>>>
>>> I guess what you are proposing is separating a Message into a 'commands' 
>>> and 'update' callbacks?  That could work well too...  I could add that as 
>>> an option to my ProgramEx testing library (where I test with extra 
>>> callbacks) if you want to play around with it?  Do you propose that 
>>> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
>>> Model -> Cmd Msg, running in sequence of command before update?  I can see 
>>> a lot of them having a lot of duplicate code though, but I guess that could 
>>> be removed from my currently testing `filters` callback to clean up the 
>>> message into more pure stateful messages.  Though if I did that I really 
>>> think I would want to make two different message types, one for filters and 
>>> one for consuming, however that may make larger API changes than would be 
>>> easy..

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
So it seems that you would have something like a `commands` callback send 
out commands, one of those would be a command just for sending messages to 
`update` without sending the original message?  (Also, it is already easy 
to make commands from messages although Cmd.fromMsg would be shorter).  So 
you are thinking of something like:
```elm

commands : Msg -> Model -> Cmd Msgcommands msg model =
  case msg of
Something blah -> Cmd.batch
  [ doSomething
  , Cmd.fromMsg MyUpdateMsg blah
  ]
update : ChangeMsg -> Model -> Modelupdate msg model =
  case msg of
MyUpdateMsg blah = { model | blah = blah }

```

I am unsure about making model changes be a command like that to be honest. 
 I'd probably opt for something more like:
```elm

commands : Msg -> Model -> Cmd Msgcommands msg model =
  case msg of
Something blah -> Cmd.batch
  [ doSomething
  ]
update : Msg -> Model -> Modelupdate msg model =
  case msg of
Something blah = { model | blah = blah }

```
Where the commands happen first then the model update, however you will 
often have to do the same calculations in both to figure out something when 
a message causes both (as some of mine do), which is duplicating effort.

Something that might work that I could see would be something like with the 
filters callback I propose:
```elm

filters : BaseMsg -> Model -> ( Msg, States Model Msg )filters msg model =
  case msg of
ReceivedAMsg blah ->
  ( Something (blah+42), States.enableAll )
commands : Msg -> Model -> Cmd Msgcommands msg model =
  case msg of
Something blah -> Cmd.batch
  [ doSomething
  ]
update : Msg -> Model -> Modelupdate msg model =
  case msg of
Something blah = { model | blah = blah }

```
But even that does the returning two things that you mention but in 
filters, although I think they are inextricably tied together so they make 
sense, maybe change `filters` to a different API like:
```elm

filters : BaseMsg -> Model -> States Model Msgfilters msg model =
  case msg of
ReceivedAMsg blah -> States.enableAll |> States.sendMsg (Something 
(blah+42))

```
Although then you have to pass forward every single message manually, which 
might not be a bad things all considered, but definitely more wordy and not 
really any more clear.  Maybe make `BaseMsg` just be `Msg` again and have 
States control whether the original message is overridden or not, that 
seems more clear to me, if no override is specified for the message then it 
just passes through the original.  I still do not think I like that though.

Cannot think that commands could be a one-off subscription either.

Eh, I am not really sure, decoupling Commands from the Updates is going to 
cause a lot of code duplication, which you could resolve via a filters 
function but then you get a lot more Message types, which although would 
make things clear, not sure of how it should follow out to the end there 
yet...  Maybe if filters had a way to send out more messages than just one, 
or different types of messages...


On Thursday, August 11, 2016 at 12:03:47 PM UTC-6, Kasey Speakman wrote:
>
> It was just something that bugged me when I first saw it in the examples, 
> and I just came to the realization of why. And I am wondering out loud what 
> it look like if they were separate things.
>
> In your example case, you could make a 3rd command that did the issued a 
> new message InfoConnectIdAssigned to separate the model bit out. The 
> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
> no-effect command). I think a shortcut method could be in order like 
> Cmd.none, but something like Cmd.fromMsg.
>
> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>>
>> I guess what you are proposing is separating a Message into a 'commands' 
>> and 'update' callbacks?  That could work well too...  I could add that as 
>> an option to my ProgramEx testing library (where I test with extra 
>> callbacks) if you want to play around with it?  Do you propose that 
>> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
>> Model -> Cmd Msg, running in sequence of command before update?  I can see 
>> a lot of them having a lot of duplicate code though, but I guess that could 
>> be removed from my currently testing `filters` callback to clean up the 
>> message into more pure stateful messages.  Though if I did that I really 
>> think I would want to make two different message types, one for filters and 
>> one for consuming, however that may make larger API changes than would be 
>> easy...  What precisely would you want it to look like?
>>
>>
>> On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>>>
>>> Just as an aside, but I quite often return a mutated model *and* 
>>> commands, such as this for the shortest example I am finding:
>>> ```elm
>>>
>>> InfoConnect uid ->
>>> ( { model | uid = uid }
>>> , Cmd.batch

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
I do like the signatures you mentioned:

`update : Msg -> Model -> Model`
`command: Msg -> Model -> Cmd Msg`

However at that point, it no longer makes sense to use the same messages 
for effects and model updates. For example:

`update: Evt -> Model -> Model`
`command: Act -> Model -> Cmd Evt`

Here, using Act for commands since Cmd is already taken. Evt for events 
(facts which have occurred).

The question then becomes how `view` would be affected. Html Msg doesn't 
work there. If you did Html Act, then there is some boilerplate for actions 
that don't have effects:

```
-- FUTURE READER: THIS IS AN EXAMPLE, NOT ACTUAL SYNTAX
command : Act -> Model -> Cmd Evt
command act model =
  case act of
ChangeName name -> 
  Cmd.fromEvt <| NameChanged name

SubmitCustomerChanges customer ->
  Cmd.batch
[ Cmd.fromEvt <| CustomerChangesSubmitted
, callServerWithCustomer customer -- or model.Customer?
]
```

An alternative is to allow Html to produce either Act or Evt. But that 
feels wrong. It would be too easy to try to use only one or the other for 
all the work.

On Thursday, August 11, 2016 at 1:03:47 PM UTC-5, Kasey Speakman wrote:
>
> It was just something that bugged me when I first saw it in the examples, 
> and I just came to the realization of why. And I am wondering out loud what 
> it look like if they were separate things.
>
> In your example case, you could make a 3rd command that did the issued a 
> new message InfoConnectIdAssigned to separate the model bit out. The 
> tradeoff is isolation of model changes vs increased boilerplate (issuing a 
> no-effect command). I think a shortcut method could be in order like 
> Cmd.none, but something like Cmd.fromMsg.
>
> On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>>
>> I guess what you are proposing is separating a Message into a 'commands' 
>> and 'update' callbacks?  That could work well too...  I could add that as 
>> an option to my ProgramEx testing library (where I test with extra 
>> callbacks) if you want to play around with it?  Do you propose that 
>> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
>> Model -> Cmd Msg, running in sequence of command before update?  I can see 
>> a lot of them having a lot of duplicate code though, but I guess that could 
>> be removed from my currently testing `filters` callback to clean up the 
>> message into more pure stateful messages.  Though if I did that I really 
>> think I would want to make two different message types, one for filters and 
>> one for consuming, however that may make larger API changes than would be 
>> easy...  What precisely would you want it to look like?
>>
>>
>> On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>>>
>>> Just as an aside, but I quite often return a mutated model *and* 
>>> commands, such as this for the shortest example I am finding:
>>> ```elm
>>>
>>> InfoConnect uid ->
>>> ( { model | uid = uid }
>>> , Cmd.batch
>>> [ connect_roomlist 0
>>> , connect_roomlist uid
>>> ]
>>> )
>>>
>>> ```
>>> So when we connected to the server, got an InfoConnect message back with 
>>> the unique ID of the user, they then are allowed to connect to both the 
>>> public and their personal room lists, so I submit those connection requests.
>>>
>>>
>>> On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:

 Hi all,

 I'm getting to know Elm. I recently read this article 
  
 about event sourcing in Elm. Essentially, the time-traveling debugger is 
 event sourcing. But it's a pattern that could be used in an app for other 
 great things. (Lots of literature on that in the internet. One particular 
 interest of mine is producing a complete failing use case from live 
 running 
 app -- it's just all the events. Obviously wouldn't work for real-time 
 apps... too many events... but for most of mine it would.)

 However, one thing that is a hindrance (to the TTD as well) and that 
 has always bothered me about the Elm examples is this signature.

 update : Msg -> Model -> (Model, Cmd Msg)


 Because an update returns both a Model and Cmd, for instance, the 
 time-traveling debugger "...needs to tell the runtime not to perform any 
 side-effects during replay to avoid these issues"[1]. An event-sourcing 
 implementation would have to figure a way to do the same without runtime 
 hooks.

 This part of the architecture mixes concerns by returning a model and 
 effects. And usually (not always) you see each message returning one or 
 the 
 other, not both. From the docs:

 update : Msg -> Model -> (Model, Cmd Msg)
 update msg model =
   case msg of
   

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
It was just something that bugged me when I first saw it in the examples, 
and I just came to the realization of why. And I am wondering out loud what 
it look like if they were separate things.

In your example case, you could make a 3rd command that did the issued a 
new message InfoConnectIdAssigned to separate the model bit out. The 
tradeoff is isolation of model changes vs increased boilerplate (issuing a 
no-effect command). I think a shortcut method could be in order like 
Cmd.none, but something like Cmd.fromMsg.

On Thursday, August 11, 2016 at 12:53:16 PM UTC-5, OvermindDL1 wrote:
>
> I guess what you are proposing is separating a Message into a 'commands' 
> and 'update' callbacks?  That could work well too...  I could add that as 
> an option to my ProgramEx testing library (where I test with extra 
> callbacks) if you want to play around with it?  Do you propose that 
> `update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
> Model -> Cmd Msg, running in sequence of command before update?  I can see 
> a lot of them having a lot of duplicate code though, but I guess that could 
> be removed from my currently testing `filters` callback to clean up the 
> message into more pure stateful messages.  Though if I did that I really 
> think I would want to make two different message types, one for filters and 
> one for consuming, however that may make larger API changes than would be 
> easy...  What precisely would you want it to look like?
>
>
> On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>>
>> Just as an aside, but I quite often return a mutated model *and* 
>> commands, such as this for the shortest example I am finding:
>> ```elm
>>
>> InfoConnect uid ->
>> ( { model | uid = uid }
>> , Cmd.batch
>> [ connect_roomlist 0
>> , connect_roomlist uid
>> ]
>> )
>>
>> ```
>> So when we connected to the server, got an InfoConnect message back with 
>> the unique ID of the user, they then are allowed to connect to both the 
>> public and their personal room lists, so I submit those connection requests.
>>
>>
>> On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:
>>>
>>> Hi all,
>>>
>>> I'm getting to know Elm. I recently read this article 
>>>  
>>> about event sourcing in Elm. Essentially, the time-traveling debugger is 
>>> event sourcing. But it's a pattern that could be used in an app for other 
>>> great things. (Lots of literature on that in the internet. One particular 
>>> interest of mine is producing a complete failing use case from live running 
>>> app -- it's just all the events. Obviously wouldn't work for real-time 
>>> apps... too many events... but for most of mine it would.)
>>>
>>> However, one thing that is a hindrance (to the TTD as well) and that has 
>>> always bothered me about the Elm examples is this signature.
>>>
>>> update : Msg -> Model -> (Model, Cmd Msg)
>>>
>>>
>>> Because an update returns both a Model and Cmd, for instance, the 
>>> time-traveling debugger "...needs to tell the runtime not to perform any 
>>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>>> implementation would have to figure a way to do the same without runtime 
>>> hooks.
>>>
>>> This part of the architecture mixes concerns by returning a model and 
>>> effects. And usually (not always) you see each message returning one or the 
>>> other, not both. From the docs:
>>>
>>> update : Msg -> Model -> (Model, Cmd Msg)
>>> update msg model =
>>>   case msg of
>>> Roll ->
>>>   (model, Random.generate NewFace (Random.int 1 6))
>>>
>>> NewFace newFace ->
>>>   (Model newFace, Cmd.none)
>>>
>>>
>>> Here, Roll does an effect, but nothing with the model. NewFace returns a 
>>> new model but no effects. You do have cases where you want to update a UI 
>>> element when an outside effect happens, like activating a spinner when 
>>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>>> One that immediately returns a separate message affecting the model's 
>>> spinner. And another to do the HTTP request.
>>>
>>> So it seems to me that there are really two concepts at work here. There 
>>> are "events" which have happened and can be used completely 
>>> deterministically, and there are commands which interface with the outside 
>>> and may produce events.
>>>
>>> I think it's something worth pointing out and considering for the 
>>> future. What do y'all think?
>>>
>>> Kasey
>>>
>>> [1] source , section "How Elm makes this 
>>> possible", subsection "Purity", last paragraph
>>>
>>

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

[elm-discuss] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
As a thing of the below example, it would be really really awesome if I 
could 'subscribe' to the connections instead of needing to actively request 
them, as in just have the subscriptions be something like this for the 
below example:
```elm

subscriptions model =
  Sub.batch
  [ if model.uid <=0 then Sub.none else RoomConnection 0 connectionMessageMapper
  , if model.uid <=0 then Sub.none else RoomConnection model.uid 
connectionMessageMapper
  , etc...
  ]

```
Or perhaps:
```elm

subscriptions model =
  Sub.batch
  [ RoomConnection 0 connectionMessageMapper `Sub.when` model.uid >0
  , RoomConnection model.uid connectionMessageMapper `Sub.when` model.uid >0
  , etc...
  ]

```

Such a way to register such things would remove my need of many commands, 
though not all for sure.


On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>
> Just as an aside, but I quite often return a mutated model *and* commands, 
> such as this for the shortest example I am finding:
> ```elm
>
> InfoConnect uid ->
> ( { model | uid = uid }
> , Cmd.batch
> [ connect_roomlist 0
> , connect_roomlist uid
> ]
> )
>
> ```
> So when we connected to the server, got an InfoConnect message back with 
> the unique ID of the user, they then are allowed to connect to both the 
> public and their personal room lists, so I submit those connection requests.
>
>
> On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:
>>
>> Hi all,
>>
>> I'm getting to know Elm. I recently read this article 
>>  about 
>> event sourcing in Elm. Essentially, the time-traveling debugger is event 
>> sourcing. But it's a pattern that could be used in an app for other great 
>> things. (Lots of literature on that in the internet. One particular 
>> interest of mine is producing a complete failing use case from live running 
>> app -- it's just all the events. Obviously wouldn't work for real-time 
>> apps... too many events... but for most of mine it would.)
>>
>> However, one thing that is a hindrance (to the TTD as well) and that has 
>> always bothered me about the Elm examples is this signature.
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>>
>>
>> Because an update returns both a Model and Cmd, for instance, the 
>> time-traveling debugger "...needs to tell the runtime not to perform any 
>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>> implementation would have to figure a way to do the same without runtime 
>> hooks.
>>
>> This part of the architecture mixes concerns by returning a model and 
>> effects. And usually (not always) you see each message returning one or the 
>> other, not both. From the docs:
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Roll ->
>>   (model, Random.generate NewFace (Random.int 1 6))
>>
>> NewFace newFace ->
>>   (Model newFace, Cmd.none)
>>
>>
>> Here, Roll does an effect, but nothing with the model. NewFace returns a 
>> new model but no effects. You do have cases where you want to update a UI 
>> element when an outside effect happens, like activating a spinner when 
>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>> One that immediately returns a separate message affecting the model's 
>> spinner. And another to do the HTTP request.
>>
>> So it seems to me that there are really two concepts at work here. There 
>> are "events" which have happened and can be used completely 
>> deterministically, and there are commands which interface with the outside 
>> and may produce events.
>>
>> I think it's something worth pointing out and considering for the future. 
>> What do y'all think?
>>
>> Kasey
>>
>> [1] source , section "How Elm makes this 
>> possible", subsection "Purity", last paragraph
>>
>

-- 
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] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
I guess what you are proposing is separating a Message into a 'commands' 
and 'update' callbacks?  That could work well too...  I could add that as 
an option to my ProgramEx testing library (where I test with extra 
callbacks) if you want to play around with it?  Do you propose that 
`update` would be `Msg -> Model -> Model` and `command` would be `Msg -> 
Model -> Cmd Msg, running in sequence of command before update?  I can see 
a lot of them having a lot of duplicate code though, but I guess that could 
be removed from my currently testing `filters` callback to clean up the 
message into more pure stateful messages.  Though if I did that I really 
think I would want to make two different message types, one for filters and 
one for consuming, however that may make larger API changes than would be 
easy...  What precisely would you want it to look like?


On Thursday, August 11, 2016 at 11:48:21 AM UTC-6, OvermindDL1 wrote:
>
> Just as an aside, but I quite often return a mutated model *and* commands, 
> such as this for the shortest example I am finding:
> ```elm
>
> InfoConnect uid ->
> ( { model | uid = uid }
> , Cmd.batch
> [ connect_roomlist 0
> , connect_roomlist uid
> ]
> )
>
> ```
> So when we connected to the server, got an InfoConnect message back with 
> the unique ID of the user, they then are allowed to connect to both the 
> public and their personal room lists, so I submit those connection requests.
>
>
> On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:
>>
>> Hi all,
>>
>> I'm getting to know Elm. I recently read this article 
>>  about 
>> event sourcing in Elm. Essentially, the time-traveling debugger is event 
>> sourcing. But it's a pattern that could be used in an app for other great 
>> things. (Lots of literature on that in the internet. One particular 
>> interest of mine is producing a complete failing use case from live running 
>> app -- it's just all the events. Obviously wouldn't work for real-time 
>> apps... too many events... but for most of mine it would.)
>>
>> However, one thing that is a hindrance (to the TTD as well) and that has 
>> always bothered me about the Elm examples is this signature.
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>>
>>
>> Because an update returns both a Model and Cmd, for instance, the 
>> time-traveling debugger "...needs to tell the runtime not to perform any 
>> side-effects during replay to avoid these issues"[1]. An event-sourcing 
>> implementation would have to figure a way to do the same without runtime 
>> hooks.
>>
>> This part of the architecture mixes concerns by returning a model and 
>> effects. And usually (not always) you see each message returning one or the 
>> other, not both. From the docs:
>>
>> update : Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>   case msg of
>> Roll ->
>>   (model, Random.generate NewFace (Random.int 1 6))
>>
>> NewFace newFace ->
>>   (Model newFace, Cmd.none)
>>
>>
>> Here, Roll does an effect, but nothing with the model. NewFace returns a 
>> new model but no effects. You do have cases where you want to update a UI 
>> element when an outside effect happens, like activating a spinner when 
>> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
>> One that immediately returns a separate message affecting the model's 
>> spinner. And another to do the HTTP request.
>>
>> So it seems to me that there are really two concepts at work here. There 
>> are "events" which have happened and can be used completely 
>> deterministically, and there are commands which interface with the outside 
>> and may produce events.
>>
>> I think it's something worth pointing out and considering for the future. 
>> What do y'all think?
>>
>> Kasey
>>
>> [1] source , section "How Elm makes this 
>> possible", subsection "Purity", last paragraph
>>
>

-- 
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] Re: More thorough side-effect isolation

2016-08-11 Thread OvermindDL1
Just as an aside, but I quite often return a mutated model *and* commands, 
such as this for the shortest example I am finding:
```elm

InfoConnect uid ->
( { model | uid = uid }
, Cmd.batch
[ connect_roomlist 0
, connect_roomlist uid
]
)

```
So when we connected to the server, got an InfoConnect message back with 
the unique ID of the user, they then are allowed to connect to both the 
public and their personal room lists, so I submit those connection requests.


On Thursday, August 11, 2016 at 11:37:48 AM UTC-6, Kasey Speakman wrote:
>
> Hi all,
>
> I'm getting to know Elm. I recently read this article 
>  about 
> event sourcing in Elm. Essentially, the time-traveling debugger is event 
> sourcing. But it's a pattern that could be used in an app for other great 
> things. (Lots of literature on that in the internet. One particular 
> interest of mine is producing a complete failing use case from live running 
> app -- it's just all the events. Obviously wouldn't work for real-time 
> apps... too many events... but for most of mine it would.)
>
> However, one thing that is a hindrance (to the TTD as well) and that has 
> always bothered me about the Elm examples is this signature.
>
> update : Msg -> Model -> (Model, Cmd Msg)
>
>
> Because an update returns both a Model and Cmd, for instance, the 
> time-traveling debugger "...needs to tell the runtime not to perform any 
> side-effects during replay to avoid these issues"[1]. An event-sourcing 
> implementation would have to figure a way to do the same without runtime 
> hooks.
>
> This part of the architecture mixes concerns by returning a model and 
> effects. And usually (not always) you see each message returning one or the 
> other, not both. From the docs:
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>   case msg of
> Roll ->
>   (model, Random.generate NewFace (Random.int 1 6))
>
> NewFace newFace ->
>   (Model newFace, Cmd.none)
>
>
> Here, Roll does an effect, but nothing with the model. NewFace returns a 
> new model but no effects. You do have cases where you want to update a UI 
> element when an outside effect happens, like activating a spinner when 
> sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
> One that immediately returns a separate message affecting the model's 
> spinner. And another to do the HTTP request.
>
> So it seems to me that there are really two concepts at work here. There 
> are "events" which have happened and can be used completely 
> deterministically, and there are commands which interface with the outside 
> and may produce events.
>
> I think it's something worth pointing out and considering for the future. 
> What do y'all think?
>
> Kasey
>
> [1] source , section "How Elm makes this 
> possible", subsection "Purity", last paragraph
>

-- 
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] More thorough side-effect isolation

2016-08-11 Thread Kasey Speakman
Hi all,

I'm getting to know Elm. I recently read this article 
 about 
event sourcing in Elm. Essentially, the time-traveling debugger is event 
sourcing. But it's a pattern that could be used in an app for other great 
things. (Lots of literature on that in the internet. One particular 
interest of mine is producing a complete failing use case from live running 
app -- it's just all the events. Obviously wouldn't work for real-time 
apps... too many events... but for most of mine it would.)

However, one thing that is a hindrance (to the TTD as well) and that has 
always bothered me about the Elm examples is this signature.

update : Msg -> Model -> (Model, Cmd Msg)


Because an update returns both a Model and Cmd, for instance, the 
time-traveling debugger "...needs to tell the runtime not to perform any 
side-effects during replay to avoid these issues"[1]. An event-sourcing 
implementation would have to figure a way to do the same without runtime 
hooks.

This part of the architecture mixes concerns by returning a model and 
effects. And usually (not always) you see each message returning one or the 
other, not both. From the docs:

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
Roll ->
  (model, Random.generate NewFace (Random.int 1 6))

NewFace newFace ->
  (Model newFace, Cmd.none)


Here, Roll does an effect, but nothing with the model. NewFace returns a 
new model but no effects. You do have cases where you want to update a UI 
element when an outside effect happens, like activating a spinner when 
sending off an HTTP request. Those could still be modeled as two "Cmd"s. 
One that immediately returns a separate message affecting the model's 
spinner. And another to do the HTTP request.

So it seems to me that there are really two concepts at work here. There 
are "events" which have happened and can be used completely 
deterministically, and there are commands which interface with the outside 
and may produce events.

I think it's something worth pointing out and considering for the future. 
What do y'all think?

Kasey

[1] source , section "How Elm makes this 
possible", subsection "Purity", last paragraph

-- 
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] Re: about the Keyboard API

2016-08-11 Thread OvermindDL1
Heh, yes I keep putting different ideas here, I am not focusing on a single 
idea, just working with the API's in testing a bit, figure out some new 
ideas, and document them here, upon which I then go out, make a mock-up of 
the ideas, and see how it works and document the results again.  Just a set 
of ideas for others to mull over as well to see if anything has merit.  And 
yep, the latest Keyboard.keyMap* could be a replacement of the existing API 
(or added to it).  From my mock testing it seems to be the easiest to use 
and most configurable thus far for this specific issue (since it is 
entirely just a simple-to-read-and-parse data structure without a host of 
mis-matched calls).


On Thursday, August 11, 2016 at 9:58:28 AM UTC-6, Janis Voigtländer wrote:
>
> You throw in a lot of different ideas. I’m getting confused.
>
> Concerning the approach with having both subscriptions and your new 
> filters hook, I still think what I wrote in my last message (about the 
> case if you were to make the same decisions as the original code about 
> which subscriptions are running when, particularly concerning the animation 
> frame ticking):
>
> However, the result will be again more complex and less readable, I think. 
> You will have the dealing with subscriptions distributed over different 
> places in the code, while the original version and also the version 
> improved by selective Keyboard functions has only one.
>
> Your new message does not seem to try to rebut this. Instead, it proposes 
> a completely different route? The Keyboard.keyMapChar and 
> Keyboard.keyMapFn etc. things. This would be intended as completely 
> replacing the current Keyboard API? As a more radical proposal than just 
> changing the types of the current Keyboard.downs etc. functions by 
> bringing Maybe into play?
> ​
>
> 2016-08-11 16:51 GMT+02:00 OvermindDL1 >:
>
>> The ticks did change yes, I originally had it testing the state first but 
>> figured, eh, I was wanting to see what a keyboard action mapper would be 
>> (which could easily be fed into a Keyboard mapper, ignore the filters 
>> stuff).
>>
>> I still find mapping the keyboard events 'inside' subscription to be very 
>> noisy.  And I still think think a single subscription for a keyboard filter 
>> would be best to prevent running and testing multiple.  Hmm, maybe 
>> something like:
>> ```elm
>>   Keyboard.keyMapChar
>> case d.state of
>>   Running ->
>> [ ( 'P', KeyDown, PauseToggle )
>> , ( ' ', KeyDown, JumpDown )
>> , ( ' ', KeyUp,   JumpUp )
>> ]
>>   _ ->
>> [ ( 'P', KeyDown, PauseToggle )
>> ]
>> ```
>>
>> I am one of those that hate inline conditionals and prefer to hoist it 
>> out, so yes I like the duplicated PauseToggle, makes it explicitly obvious 
>> that it is working in each state instead of noise like ++ and such making 
>> you have to think more.  However I think that is wonderfully readable and 
>> could easily register and unregister subscriptions as needed while making 
>> configurable key mapping much easier (since no need to convert to if/then 
>> repeating or dict lookups or so).
>>
>> Or as a full example the above could be:
>> ```elm
>> subscriptions : GameData -> Sub GameMsg
>> subscriptions =
>>   case d.state of
>> Running ->
>>   Sub.batch
>> [ AnimationFrame.diffs Tick
>> , Keyboard.keyMapChar
>>   [ ( 'P', KeyDown, PauseToggle )
>>   , ( ' ', KeyDown, JumpDown )
>>   , ( ' ', KeyUp,   JumpUp )
>>   ]
>> ]
>> _ -> Keyboard.keyMapChar [ ( 'P', KeyDown, PauseToggle ) ]
>> ```
>>
>> Which I also think is far more readable (embedding state tests are always 
>> unreadable).
>>
>> A `Keyboard.keyMapFn` could also make the first element of the tuple be 
>> a function that is passed in a keycode so it can do its own testing via 
>> returning True/False.  Or could just make it a `Keyboard.keyMap` where 
>> the first element is a subtype to become `( KeyMap.Char 'P', KeyDown, 
>> PauseToggle )` or `KeyMap.Fn` or whatever other options.  Would make it 
>> easier to expand later as well with more functionality if ever desired.
>>
>> As always, lots of ways to go with various designs.
>>
>>
>> On Wednesday, August 10, 2016 at 8:53:32 PM UTC-6, Janis Voigtländer 
>> wrote:
>>>
>>> You did change the behavior, though. Specifically, AnimationFrame.ticks 
>>> is always running in your version, even when the game is paused. Similarly 
>>> for some of the other subscriptions. As discussed in the generic 
>>> subscription filtering thread, it's best to turn off subscriptions 
>>> completely whenever possible. Of course, you could adapt your version of 
>>> the subscriptions-function to bring the turning-off-of-subscriptions back. 
>>> However, the result will be again more complex and less readable, I think. 
>>> You will have the dealing with subscriptions distributed over different 
>>> places in the code, while the original 

Re: [elm-discuss] Re: about the Keyboard API

2016-08-11 Thread Janis Voigtländer
You throw in a lot of different ideas. I’m getting confused.

Concerning the approach with having both subscriptions and your new filters
hook, I still think what I wrote in my last message (about the case if you
were to make the same decisions as the original code about which
subscriptions are running when, particularly concerning the animation frame
ticking):

However, the result will be again more complex and less readable, I think.
You will have the dealing with subscriptions distributed over different
places in the code, while the original version and also the version
improved by selective Keyboard functions has only one.

Your new message does not seem to try to rebut this. Instead, it proposes a
completely different route? The Keyboard.keyMapChar and Keyboard.keyMapFn
etc. things. This would be intended as completely replacing the current
Keyboard API? As a more radical proposal than just changing the types of
the current Keyboard.downs etc. functions by bringing Maybe into play?
​

2016-08-11 16:51 GMT+02:00 OvermindDL1 :

> The ticks did change yes, I originally had it testing the state first but
> figured, eh, I was wanting to see what a keyboard action mapper would be
> (which could easily be fed into a Keyboard mapper, ignore the filters
> stuff).
>
> I still find mapping the keyboard events 'inside' subscription to be very
> noisy.  And I still think think a single subscription for a keyboard filter
> would be best to prevent running and testing multiple.  Hmm, maybe
> something like:
> ```elm
>   Keyboard.keyMapChar
> case d.state of
>   Running ->
> [ ( 'P', KeyDown, PauseToggle )
> , ( ' ', KeyDown, JumpDown )
> , ( ' ', KeyUp,   JumpUp )
> ]
>   _ ->
> [ ( 'P', KeyDown, PauseToggle )
> ]
> ```
>
> I am one of those that hate inline conditionals and prefer to hoist it
> out, so yes I like the duplicated PauseToggle, makes it explicitly obvious
> that it is working in each state instead of noise like ++ and such making
> you have to think more.  However I think that is wonderfully readable and
> could easily register and unregister subscriptions as needed while making
> configurable key mapping much easier (since no need to convert to if/then
> repeating or dict lookups or so).
>
> Or as a full example the above could be:
> ```elm
> subscriptions : GameData -> Sub GameMsg
> subscriptions =
>   case d.state of
> Running ->
>   Sub.batch
> [ AnimationFrame.diffs Tick
> , Keyboard.keyMapChar
>   [ ( 'P', KeyDown, PauseToggle )
>   , ( ' ', KeyDown, JumpDown )
>   , ( ' ', KeyUp,   JumpUp )
>   ]
> ]
> _ -> Keyboard.keyMapChar [ ( 'P', KeyDown, PauseToggle ) ]
> ```
>
> Which I also think is far more readable (embedding state tests are always
> unreadable).
>
> A `Keyboard.keyMapFn` could also make the first element of the tuple be a
> function that is passed in a keycode so it can do its own testing via
> returning True/False.  Or could just make it a `Keyboard.keyMap` where
> the first element is a subtype to become `( KeyMap.Char 'P', KeyDown,
> PauseToggle )` or `KeyMap.Fn` or whatever other options.  Would make it
> easier to expand later as well with more functionality if ever desired.
>
> As always, lots of ways to go with various designs.
>
>
> On Wednesday, August 10, 2016 at 8:53:32 PM UTC-6, Janis Voigtländer wrote:
>>
>> You did change the behavior, though. Specifically, AnimationFrame.ticks
>> is always running in your version, even when the game is paused. Similarly
>> for some of the other subscriptions. As discussed in the generic
>> subscription filtering thread, it's best to turn off subscriptions
>> completely whenever possible. Of course, you could adapt your version of
>> the subscriptions-function to bring the turning-off-of-subscriptions back.
>> However, the result will be again more complex and less readable, I think.
>> You will have the dealing with subscriptions distributed over different
>> places in the code, while the original version and also the version
>> improved by selective Keyboard functions has only one.
>
> --
> 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.


Re: [elm-discuss] What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread John Orford
the two themes I learned were:

simplicity & accuracy

simplicity: fewer concepts to learn than most languages

accuracy: following on from simplicity, lack of 'features' to shoot
yourself in the foot, leads to type checking and guarantee goodness

On Thu, 11 Aug 2016 at 16:59 Leroy Campbell  wrote:

> I'd say learning how to make illegal states unrepresentable.
>
> https://vimeo.com/162036084
>
> --
> 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] What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Leroy Campbell
I'd say learning how to make illegal states unrepresentable.

https://vimeo.com/162036084

-- 
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] Re: [ANN] elm-mdl 7.0.0 — supports all components of Material Design Lite

2016-08-11 Thread OvermindDL1
MDL is a mostly-javascript-driven-with-css helpers for the complicated 
Material stuff, for the rest of it you can do whatever you want, including 
using elm-html (elm-mdl is designed to add to elm-html, not replace it).


On Wednesday, August 10, 2016 at 9:58:58 PM UTC-6, David Legard wrote:
>
> Does Google's MDL spec include the concept of clickable images?
>
> I need to present a multi-lingual site where the language is changed by 
> clicking on a small PNG flag.
>
> It's easy to do in elm-html
>
> ..
> img [ src ("UK.png"),flagstyle, onClick English] []
>
> ..
>
> .. but I don't see in in the MDL spec or the elm-mdl implementation.
>
> Or should I be mixing the two approaches - elm-mdl with elm-html?
>

-- 
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] Re: about the Keyboard API

2016-08-11 Thread OvermindDL1
The ticks did change yes, I originally had it testing the state first but 
figured, eh, I was wanting to see what a keyboard action mapper would be 
(which could easily be fed into a Keyboard mapper, ignore the filters 
stuff).

I still find mapping the keyboard events 'inside' subscription to be very 
noisy.  And I still think think a single subscription for a keyboard filter 
would be best to prevent running and testing multiple.  Hmm, maybe 
something like:
```elm
  Keyboard.keyMapChar
case d.state of
  Running ->
[ ( 'P', KeyDown, PauseToggle )
, ( ' ', KeyDown, JumpDown )
, ( ' ', KeyUp,   JumpUp )
]
  _ ->
[ ( 'P', KeyDown, PauseToggle )
]
```

I am one of those that hate inline conditionals and prefer to hoist it out, 
so yes I like the duplicated PauseToggle, makes it explicitly obvious that 
it is working in each state instead of noise like ++ and such making you 
have to think more.  However I think that is wonderfully readable and could 
easily register and unregister subscriptions as needed while making 
configurable key mapping much easier (since no need to convert to if/then 
repeating or dict lookups or so).

Or as a full example the above could be:
```elm
subscriptions : GameData -> Sub GameMsg
subscriptions =
  case d.state of
Running ->
  Sub.batch
[ AnimationFrame.diffs Tick
, Keyboard.keyMapChar
  [ ( 'P', KeyDown, PauseToggle )
  , ( ' ', KeyDown, JumpDown )
  , ( ' ', KeyUp,   JumpUp )
  ]
]
_ -> Keyboard.keyMapChar [ ( 'P', KeyDown, PauseToggle ) ]
```

Which I also think is far more readable (embedding state tests are always 
unreadable).

A `Keyboard.keyMapFn` could also make the first element of the tuple be a 
function that is passed in a keycode so it can do its own testing via 
returning True/False.  Or could just make it a `Keyboard.keyMap` where the 
first element is a subtype to become `( KeyMap.Char 'P', KeyDown, 
PauseToggle )` or `KeyMap.Fn` or whatever other options.  Would make it 
easier to expand later as well with more functionality if ever desired.

As always, lots of ways to go with various designs.


On Wednesday, August 10, 2016 at 8:53:32 PM UTC-6, Janis Voigtländer wrote:
>
> You did change the behavior, though. Specifically, AnimationFrame.ticks is 
> always running in your version, even when the game is paused. Similarly for 
> some of the other subscriptions. As discussed in the generic subscription 
> filtering thread, it's best to turn off subscriptions completely whenever 
> possible. Of course, you could adapt your version of the 
> subscriptions-function to bring the turning-off-of-subscriptions back. 
> However, the result will be again more complex and less readable, I think. 
> You will have the dealing with subscriptions distributed over different 
> places in the code, while the original version and also the version 
> improved by selective Keyboard functions has only one. 

-- 
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] Re: What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Max Goldstein
Immutability and purity are classic examples but they both talk about what is 
NOT possible. That won't mean much to someone new to programming. I'd like to 
add "a small number of powerful constructs" instead of many special cases. This 
implies that you should accept the language as it is instead of trying to add 
to it. Which implies TEA and use-case driven design. These are more attitudes 
than ideas, though. 

-- 
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] Why "type alias" instead of just "type" for record declaration

2016-08-11 Thread Peter Damoc
Think about tuples. You can have a type like `(Int, Int)`, and you can use
it in your function annotations.

Now, you can reference this type with an alias too like `type alias
TwoIntsTuple = (Int, Int)`
TwoIntsTuple will not be a new type, it is the old type `(Int, Int)` that
you can now reference with a new name that makes more sense to you.

In the same way, you could use the record  { x : Int, y : Int } all over
your code OR, you can give it a name (alias) like `type alias Point = { x :
Int, y : Int}`

If you want different behavior, you hide the record behind a tag and make
sure that all the values are valid.

`type SafePoint = SafePoint { x : Int, y: Int}` or, using the above alias
`type SafePoint = SafePoint Point`

This way you are actually creating a new type. You can have functions over
this type that work ONLY on this type and not on all the  { x : Int, y :
Int}
You can be sure for example that x will never be negative or y will never
be over some number because you control all the operations.

Another point. All the unions in Elm are tagged unions, so, `type X  = T1
| T2` will only work if T1 and T2 are just tags. If they are types, you
need to tag them like `type X = A T1 | B T2`



On Thu, Aug 11, 2016 at 2:14 PM, Franček Prijatelj <
prijatelj.fran...@gmail.com> wrote:

> Hi
>
> I am asking why* type alias* instead of just *type*, to declare record.
>
> type X
> = T1
> | T2
>
>
> type alias X1 =
> X
>
> *-- why not just type here*
> type alias Y =
> { a : Int
> , b : Int
> }
>
>
> type alias Y1 =
> Y
>
>
> Samples:
>
>
> a1  : X  -- Ok
> a2  : X1 -- Ok
> a3 : T1  | T2-- Error
>
>
> b1 : Y-- Ok
> b2 : Y1   -- Ok
> b3 : { a: Int , b : Int } -- Ok
>
>
>
> regards
> Franček
>
> --
> 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.
>



-- 
There is NO FATE, we are the creators.
blog: http://damoc.ro/

-- 
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] Why "type alias" instead of just "type" for record declaration

2016-08-11 Thread Franček Prijatelj
Hi

I am asking why* type alias* instead of just *type*, to declare record. 

type X
= T1
| T2


type alias X1 =
X

*-- why not just type here*
type alias Y =
{ a : Int
, b : Int
}


type alias Y1 =
Y


Samples:


a1  : X  -- Ok
a2  : X1 -- Ok
a3 : T1  | T2-- Error


b1 : Y-- Ok
b2 : Y1   -- Ok
b3 : { a: Int , b : Int } -- Ok



regards
Franček 

-- 
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] Re: What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Mukesh Soni
Immutability

On Thursday, August 11, 2016 at 2:37:33 PM UTC+5:30, Peter Damoc wrote:
>
> "The fundamental fact about learning: Anything is easy if you can 
> assimilate it to your collection of models. If you can't, anything can be 
> painfully difficult.” - Seymour Papert
>
> I'm trying to come up with a sorted list of concepts and models that a 
> prospective Elm user needs to learn in order become proficient in Elm. 
>
> Here is my list (I actively tried to keep it short) : 
>
> - types : the concept that information flowing through an Elm program has 
> a specific type and that the compiler will not accept the wrong type. 
>
> - type composition: the concept that types can be composed into more 
> advanced types using union type syntax and record syntax. 
>
> - type variables : the concept that you can have a type constructor that 
> can take arguments and produce a custom type (List, Maybe, etc) 
>
> - functions as types: the concept that you can give functions to other 
> functions in order to customize their application. 
>
> - currying/closures: the concept that you can take a multi argument 
> function and produce another function that has some of those arguments 
> applied. 
>
> - declarative: the concept that the Elm programs are made of one big 
> function that returns a specific type instead of a series of instructions.  
>
> How does your list looks like? Which one gave you most troubles? Which one 
> did you find most  amazing | useful | mind-blowing ? 
>
>
>
>  
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
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] Re: What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread David Legard
Not so much Elm itself, but functional programming in general.

What wouldn't lodge into my thinking was: immutability + the complete lack 
of variables + and no global scope.

How do you achieve stuff if you can't write x = x + 1 ?

It took me ages to get comfortable with the functional way of doing things. 
Now, like all other converts, I tend to write "functionally" even when I'm 
using an OO language

-- 
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] What concepts and models did you had to learn in order to be able to write good Elm code?

2016-08-11 Thread Peter Damoc
"The fundamental fact about learning: Anything is easy if you can
assimilate it to your collection of models. If you can't, anything can be
painfully difficult.” - Seymour Papert

I'm trying to come up with a sorted list of concepts and models that a
prospective Elm user needs to learn in order become proficient in Elm.

Here is my list (I actively tried to keep it short) :

- types : the concept that information flowing through an Elm program has a
specific type and that the compiler will not accept the wrong type.

- type composition: the concept that types can be composed into more
advanced types using union type syntax and record syntax.

- type variables : the concept that you can have a type constructor that
can take arguments and produce a custom type (List, Maybe, etc)

- functions as types: the concept that you can give functions to other
functions in order to customize their application.

- currying/closures: the concept that you can take a multi argument
function and produce another function that has some of those arguments
applied.

- declarative: the concept that the Elm programs are made of one big
function that returns a specific type instead of a series of instructions.

How does your list looks like? Which one gave you most troubles? Which one
did you find most  amazing | useful | mind-blowing ?





-- 
There is NO FATE, we are the creators.
blog: http://damoc.ro/

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