Re: [elm-discuss] Structure for large Elm apps

2016-10-24 Thread Mark Hamburg
I don't know what I was thinking when I wrote that. The code I just
provided can't actually cycle. We can go from updateView to updateData to
updateViewForData, but then we're done.

Mark

On Mon, Oct 24, 2016 at 12:36 PM, Mark Hamburg 
wrote:

> So, your "data model" is a list of users but your "view model" is a
> boolean state for each user? I'm working on thinking about how that would
> come up but I guess the checkboxes could be for selection and the selection
> could be view specific.
>
> Anyway, here is my quick effort at breaking this out. I'm going to assume
> that we can represent users with strings. If they need more data, then
> there is presumably a way to convert a user into a user-id for internal use
> and a string for display. So, our data model is:
>
> type alias User = String
>
> type alias DataModel = List User
>
>
> -- In model:
>
> dataModel : DataModel
>
>
> The view model consists of the information for each checkbox which
> assuming it's a checkbox really is just a boolean state. We maintain this
> as a dictionary indexed by user:
>
> type alias ViewModel = Dict User Bool
>
>
> -- In model:
>
> viewModel : ViewModel
>
> The view function can now map over the data model (list of users) and
> extract the extra view model information by consulting the dictionary.
>
> Changes to the checkbox state, just write values back into the view model
> dictionary.
>
> Changes to the user list need to update the data model but then they also
> need to update the view model to remove any users no longer on the list and
> add entries for any users newly on the list. (Alternatively, one could use
> the initial state for users as a default and use Maybe.withDefault to
> handle new users. Then one just needs to remove the view model entries for
> users no longer in the data model.)
>
> The key thing in structuring this is that you can build all of the logic
> that works on the data model independent of the checkbox states needed by
> the view model. For example, if these checkboxes represent selected users,
> you could have the changes to the data model be driven by a set of users.
> Events would flow into the view model collecting up this selected set and
> then turn into a message or operation for the data model. That change to
> the data model would then result in an update to the view model.
>
> Potential type signatures could be:
>
> view : DataModel -> ViewModel -> Html ViewMsg
>
> updateView : ViewMsg -> ViewModel -> (ViewModel, Cmd ViewMsg, Maybe
> DataMsg)
>
> updateData: DataMsg -> DataModel -> (DataModel, Cmd DataMsg)
>
> updateViewForData: DataModel -> ViewModel -> (ViewModel, Cmd ViewMsg)
>
> Then we get something like the following at the model level:
>
> type alias Model = { dataModel : DataModel, viewModel : ViewModel }
>
> type Msg = ToData DataMsg | ToView ViewMsg
>
> update : Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>
> case msg of
>
> ToData dataMsg ->
>
> let
>
> (newData, dataCmd ) = updateData dataMsg model.dataModel
>
> (newView, viewCmd ) = updateViewForData newData model.viewModel
>
> in
>
> ( { model | dataModel = newData, viewModel = newView }
>
> , Cmd.batch [ Cmd.map ToData dataCmd, Cmd.map ToView viewCmd ]
>
> )
>
> ToView viewMsg ->
>
> updateView viewMsg model.viewModel
>
> |> OutMessage.mapComponent (\newView -> { model | viewModel = newView })
>
> |> OutMessage.mapCmd ToView
>
> |> OutMessage.evaluateMaybe (\dataMsg m -> update (ToData dataMsg) m)
>
>
> (You can find OutMessage here: http://package.elm-lang.
> org/packages/folkertdev/outmessage/1.0.2/OutMessage)
>
> This does have the potential for pinging back and forth between data model
> updates and view updates but that's a hazard in any two component system.
> The key thing is that the model can be built and in operation can evolve
> independent of the view or views. The potentially more ugly problem comes
> if it is difficult to factor the response to a view message into logic that
> can just update the current view model and then generic logic that can
> respond to a data model change.
>
> Mark
>
> On Mon, Oct 24, 2016 at 4:29 AM, Oliver Searle-Barnes 
> wrote:
>
>> @Mark this is a pattern I've been exploring recently. An area that I
>> haven't found a solution to is keeping the view model in sync with the
>> shared models. For instance, let's say I have a view with a list of
>> checkboxes next to each user. The state for the checkboxes would be kept in
>> the view model, but then I need to manage adding/removing checkboxes as the
>> list of users changes. Currently I handle this by having a default state
>> for the checkbox which is used until a user actually clicks on a checkbox
>> at which point the state is added to the view model. This works but is
>> semantically awkward and doesn't take care of removing the checkbox state
>> if a user is removed from the shared list. https://github.com/elm-lang/ht
>> ml/issues/19 provides a potential avenue for cleanup, but even then the
>> lifecycle seems a

Re: [elm-discuss] Structure for large Elm apps

2016-10-24 Thread Mark Hamburg
So, your "data model" is a list of users but your "view model" is a boolean
state for each user? I'm working on thinking about how that would come up
but I guess the checkboxes could be for selection and the selection could
be view specific.

Anyway, here is my quick effort at breaking this out. I'm going to assume
that we can represent users with strings. If they need more data, then
there is presumably a way to convert a user into a user-id for internal use
and a string for display. So, our data model is:

type alias User = String

type alias DataModel = List User


-- In model:

dataModel : DataModel


The view model consists of the information for each checkbox which assuming
it's a checkbox really is just a boolean state. We maintain this as a
dictionary indexed by user:

type alias ViewModel = Dict User Bool


-- In model:

viewModel : ViewModel

The view function can now map over the data model (list of users) and
extract the extra view model information by consulting the dictionary.

Changes to the checkbox state, just write values back into the view model
dictionary.

Changes to the user list need to update the data model but then they also
need to update the view model to remove any users no longer on the list and
add entries for any users newly on the list. (Alternatively, one could use
the initial state for users as a default and use Maybe.withDefault to
handle new users. Then one just needs to remove the view model entries for
users no longer in the data model.)

The key thing in structuring this is that you can build all of the logic
that works on the data model independent of the checkbox states needed by
the view model. For example, if these checkboxes represent selected users,
you could have the changes to the data model be driven by a set of users.
Events would flow into the view model collecting up this selected set and
then turn into a message or operation for the data model. That change to
the data model would then result in an update to the view model.

Potential type signatures could be:

view : DataModel -> ViewModel -> Html ViewMsg

updateView : ViewMsg -> ViewModel -> (ViewModel, Cmd ViewMsg, Maybe DataMsg)

updateData: DataMsg -> DataModel -> (DataModel, Cmd DataMsg)

updateViewForData: DataModel -> ViewModel -> (ViewModel, Cmd ViewMsg)

Then we get something like the following at the model level:

type alias Model = { dataModel : DataModel, viewModel : ViewModel }

type Msg = ToData DataMsg | ToView ViewMsg

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

case msg of

ToData dataMsg ->

let

(newData, dataCmd ) = updateData dataMsg model.dataModel

(newView, viewCmd ) = updateViewForData newData model.viewModel

in

( { model | dataModel = newData, viewModel = newView }

, Cmd.batch [ Cmd.map ToData dataCmd, Cmd.map ToView viewCmd ]

)

ToView viewMsg ->

updateView viewMsg model.viewModel

|> OutMessage.mapComponent (\newView -> { model | viewModel = newView })

|> OutMessage.mapCmd ToView

|> OutMessage.evaluateMaybe (\dataMsg m -> update (ToData dataMsg) m)


(You can find OutMessage here:
http://package.elm-lang.org/packages/folkertdev/outmessage/1.0.2/OutMessage)

This does have the potential for pinging back and forth between data model
updates and view updates but that's a hazard in any two component system.
The key thing is that the model can be built and in operation can evolve
independent of the view or views. The potentially more ugly problem comes
if it is difficult to factor the response to a view message into logic that
can just update the current view model and then generic logic that can
respond to a data model change.

Mark

On Mon, Oct 24, 2016 at 4:29 AM, Oliver Searle-Barnes 
wrote:

> @Mark this is a pattern I've been exploring recently. An area that I
> haven't found a solution to is keeping the view model in sync with the
> shared models. For instance, let's say I have a view with a list of
> checkboxes next to each user. The state for the checkboxes would be kept in
> the view model, but then I need to manage adding/removing checkboxes as the
> list of users changes. Currently I handle this by having a default state
> for the checkbox which is used until a user actually clicks on a checkbox
> at which point the state is added to the view model. This works but is
> semantically awkward and doesn't take care of removing the checkbox state
> if a user is removed from the shared list. https://github.com/elm-lang/
> html/issues/19 provides a potential avenue for cleanup, but even then the
> lifecycle seems a little awkward.
>
> I wonder if you have a different approach for this problem?
>
>
> On Sunday, 23 October 2016 21:29:23 UTC+2, Mark Hamburg wrote:
>>
>> We're just getting into having an app where this is likely to matter, but
>> if you have multiple views onto the same data, then the pattern that would
>> seem to apply is to have a single data model and multiple view models. The
>> data model handles the shared part. The view models handle

Re: [elm-discuss] Structure for large Elm apps

2016-10-24 Thread Erik Lott

>
> Above all of this, the other key subdivision we are making in our SPA and 
> that I would recommend having seen where other programmers often first 
> head, is having a top layer that handles overall app state — e.g., logged 
> in v not logged in — as a type union. This can also often be where the 
> routing logic plugs in. 


This is exactly what we do throughout our entire SPA app. We use union 
types to manage overall state and protect our invariants, making it 
impossible for the app to be in an invalid state at any time. The union 
types may get a little deep at times, but the payoff is more than worth it. 

On Sunday, October 23, 2016 at 3:29:23 PM UTC-4, Mark Hamburg wrote:
>
> We're just getting into having an app where this is likely to matter, but 
> if you have multiple views onto the same data, then the pattern that would 
> seem to apply is to have a single data model and multiple view models. The 
> data model handles the shared part. The view models handle things specific 
> to the particular view — e.g., is a spin down open, what's the scroll 
> position, etc. The view functions would take the data model and their 
> particular view model as parameters and would generate appropriately tagged 
> messages back. This avoids significant nesting while still providing some 
> structure to keep pieces that can be separated separate.
>
> There are then a couple ways to structure the multiple view models. One is 
> to have a view selector but keep all of the view models alive all the time. 
> The benefit of this is that when you switch back to a view, it will 
> remember where you were. The downside is that one is carrying around — and 
> potentially updating if the view model depends on the data model — an 
> increasing number of view models if you have an increasing number of views. 
> The alternative is to put the view models into a union type and have one 
> model entry that serves as both view selector and view model storage. This 
> keeps things lighter weight but means that you have nowhere to maintain 
> context when switching back and forth.
>
> Above all of this, the other key subdivision we are making in our SPA and 
> that I would recommend having seen where other programmers often first 
> head, is having a top layer that handles overall app state — e.g., logged 
> in v not logged in — as a type union. This can also often be where the 
> routing logic plugs in. People who haven't spent a lot of time thinking in 
> terms of type unions tend to load their model up with a lot of fields that 
> only have meaning in certain states. This then leads to more invariants 
> about the state that can't be enforced by the compiler. Breaking things up 
> into different type cases for different states allows one to make more bad 
> states simply impossible. For example, our logging in state has a 
> RemoteData.WebData User reflecting whether we've gotten valid user data 
> back from the server but our logged in state simply has a User. The top 
> level event dispatcher works with the following type signature on the log 
> in state update:
>
> update : Login.Msg -> Login.Model -> ( Login.Model, Cmd Login.Msg, Maybe 
> User )
>
>
> After each call to update, it can check to see whether we now have a valid 
> user and if so switch to the logged in state, initializing it with the 
> supplied user.
>
> This isn't as flat as some people go, but it doesn't spread things out 
> into lots of components and the top layer(s) are pretty simple.
>
> Mark
>
>
> On Sun, Oct 23, 2016 at 11:39 AM, Francois  > wrote:
>
>> Hi,
>>
>> I'm really new to Elm. I'm not good enough to propose a guideline about 
>> Elm app structure but as a novice a guideline can help lots of people.
>>
>> I worked / works on a large angular application and John Papa Styleguide 
>> has been really helpful at the beginning.
>> So writing a community guideline can be a great resource. (there is 
>> another thread inter component that seems related)
>>
>> For example, on the server side, structuring domain core by features is 
>> good thing (for me). Help define some boundaries and help maintability. 
>> Grouping all Java classes by technical aspect at the project root : all 
>> services in one package, all models in one package can be tedious.
>>
>> On the front, if I correctly understood this thread :
>> - a unique Msg / Model inside Main.elm can be a good starting point and 
>> easy to refactor later. 
>> - separating the view per feature (only view functions) : advice taken 
>> from Dave
>> - break Model / Msg when too big (definition of "too big" is perhaps not 
>> easy, or someone can give some advices to detect "a too big Msg"). At this 
>> point, break Msg / Model / Update by feature. It is not all or nothing, 
>> just extract at first one feature and put them inside a file. Then the Main 
>> module wraps the feature (using map inside the Update).
>>
>> Can we imagine starting a community guideline somewhere ? adding examples 
>> lat

Re: [elm-discuss] Structure for large Elm apps

2016-10-24 Thread Oliver Searle-Barnes
@Mark this is a pattern I've been exploring recently. An area that I 
haven't found a solution to is keeping the view model in sync with the 
shared models. For instance, let's say I have a view with a list of 
checkboxes next to each user. The state for the checkboxes would be kept in 
the view model, but then I need to manage adding/removing checkboxes as the 
list of users changes. Currently I handle this by having a default state 
for the checkbox which is used until a user actually clicks on a checkbox 
at which point the state is added to the view model. This works but is 
semantically awkward and doesn't take care of removing the checkbox state 
if a user is removed from the shared list. 
https://github.com/elm-lang/html/issues/19 provides a potential avenue for 
cleanup, but even then the lifecycle seems a little awkward. 

I wonder if you have a different approach for this problem?


On Sunday, 23 October 2016 21:29:23 UTC+2, Mark Hamburg wrote:
>
> We're just getting into having an app where this is likely to matter, but 
> if you have multiple views onto the same data, then the pattern that would 
> seem to apply is to have a single data model and multiple view models. The 
> data model handles the shared part. The view models handle things specific 
> to the particular view — e.g., is a spin down open, what's the scroll 
> position, etc. The view functions would take the data model and their 
> particular view model as parameters and would generate appropriately tagged 
> messages back. This avoids significant nesting while still providing some 
> structure to keep pieces that can be separated separate.
>
> There are then a couple ways to structure the multiple view models. One is 
> to have a view selector but keep all of the view models alive all the time. 
> The benefit of this is that when you switch back to a view, it will 
> remember where you were. The downside is that one is carrying around — and 
> potentially updating if the view model depends on the data model — an 
> increasing number of view models if you have an increasing number of views. 
> The alternative is to put the view models into a union type and have one 
> model entry that serves as both view selector and view model storage. This 
> keeps things lighter weight but means that you have nowhere to maintain 
> context when switching back and forth.
>
> Above all of this, the other key subdivision we are making in our SPA and 
> that I would recommend having seen where other programmers often first 
> head, is having a top layer that handles overall app state — e.g., logged 
> in v not logged in — as a type union. This can also often be where the 
> routing logic plugs in. People who haven't spent a lot of time thinking in 
> terms of type unions tend to load their model up with a lot of fields that 
> only have meaning in certain states. This then leads to more invariants 
> about the state that can't be enforced by the compiler. Breaking things up 
> into different type cases for different states allows one to make more bad 
> states simply impossible. For example, our logging in state has a 
> RemoteData.WebData User reflecting whether we've gotten valid user data 
> back from the server but our logged in state simply has a User. The top 
> level event dispatcher works with the following type signature on the log 
> in state update:
>
> update : Login.Msg -> Login.Model -> ( Login.Model, Cmd Login.Msg, Maybe 
> User )
>
>
> After each call to update, it can check to see whether we now have a valid 
> user and if so switch to the logged in state, initializing it with the 
> supplied user.
>
> This isn't as flat as some people go, but it doesn't spread things out 
> into lots of components and the top layer(s) are pretty simple.
>
> Mark
>
>
> On Sun, Oct 23, 2016 at 11:39 AM, Francois  > wrote:
>
>> Hi,
>>
>> I'm really new to Elm. I'm not good enough to propose a guideline about 
>> Elm app structure but as a novice a guideline can help lots of people.
>>
>> I worked / works on a large angular application and John Papa Styleguide 
>> has been really helpful at the beginning.
>> So writing a community guideline can be a great resource. (there is 
>> another thread inter component that seems related)
>>
>> For example, on the server side, structuring domain core by features is 
>> good thing (for me). Help define some boundaries and help maintability. 
>> Grouping all Java classes by technical aspect at the project root : all 
>> services in one package, all models in one package can be tedious.
>>
>> On the front, if I correctly understood this thread :
>> - a unique Msg / Model inside Main.elm can be a good starting point and 
>> easy to refactor later. 
>> - separating the view per feature (only view functions) : advice taken 
>> from Dave
>> - break Model / Msg when too big (definition of "too big" is perhaps not 
>> easy, or someone can give some advices to detect "a too big Msg"). At this 
>> point, break Msg / Model 

Re: [elm-discuss] Structure for large Elm apps

2016-10-23 Thread Mark Hamburg
We're just getting into having an app where this is likely to matter, but
if you have multiple views onto the same data, then the pattern that would
seem to apply is to have a single data model and multiple view models. The
data model handles the shared part. The view models handle things specific
to the particular view — e.g., is a spin down open, what's the scroll
position, etc. The view functions would take the data model and their
particular view model as parameters and would generate appropriately tagged
messages back. This avoids significant nesting while still providing some
structure to keep pieces that can be separated separate.

There are then a couple ways to structure the multiple view models. One is
to have a view selector but keep all of the view models alive all the time.
The benefit of this is that when you switch back to a view, it will
remember where you were. The downside is that one is carrying around — and
potentially updating if the view model depends on the data model — an
increasing number of view models if you have an increasing number of views.
The alternative is to put the view models into a union type and have one
model entry that serves as both view selector and view model storage. This
keeps things lighter weight but means that you have nowhere to maintain
context when switching back and forth.

Above all of this, the other key subdivision we are making in our SPA and
that I would recommend having seen where other programmers often first
head, is having a top layer that handles overall app state — e.g., logged
in v not logged in — as a type union. This can also often be where the
routing logic plugs in. People who haven't spent a lot of time thinking in
terms of type unions tend to load their model up with a lot of fields that
only have meaning in certain states. This then leads to more invariants
about the state that can't be enforced by the compiler. Breaking things up
into different type cases for different states allows one to make more bad
states simply impossible. For example, our logging in state has a
RemoteData.WebData User reflecting whether we've gotten valid user data
back from the server but our logged in state simply has a User. The top
level event dispatcher works with the following type signature on the log
in state update:

update : Login.Msg -> Login.Model -> ( Login.Model, Cmd Login.Msg, Maybe
User )


After each call to update, it can check to see whether we now have a valid
user and if so switch to the logged in state, initializing it with the
supplied user.

This isn't as flat as some people go, but it doesn't spread things out into
lots of components and the top layer(s) are pretty simple.

Mark


On Sun, Oct 23, 2016 at 11:39 AM, Francois 
wrote:

> Hi,
>
> I'm really new to Elm. I'm not good enough to propose a guideline about
> Elm app structure but as a novice a guideline can help lots of people.
>
> I worked / works on a large angular application and John Papa Styleguide
> has been really helpful at the beginning.
> So writing a community guideline can be a great resource. (there is
> another thread inter component that seems related)
>
> For example, on the server side, structuring domain core by features is
> good thing (for me). Help define some boundaries and help maintability.
> Grouping all Java classes by technical aspect at the project root : all
> services in one package, all models in one package can be tedious.
>
> On the front, if I correctly understood this thread :
> - a unique Msg / Model inside Main.elm can be a good starting point and
> easy to refactor later.
> - separating the view per feature (only view functions) : advice taken
> from Dave
> - break Model / Msg when too big (definition of "too big" is perhaps not
> easy, or someone can give some advices to detect "a too big Msg"). At this
> point, break Msg / Model / Update by feature. It is not all or nothing,
> just extract at first one feature and put them inside a file. Then the Main
> module wraps the feature (using map inside the Update).
>
> Can we imagine starting a community guideline somewhere ? adding examples
> later.
> Really easy for me to say that.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elm-discuss+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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] Structure for large Elm apps

2016-10-23 Thread Francois
Hi,

I'm really new to Elm. I'm not good enough to propose a guideline about Elm 
app structure but as a novice a guideline can help lots of people.

I worked / works on a large angular application and John Papa Styleguide 
has been really helpful at the beginning.
So writing a community guideline can be a great resource. (there is another 
thread inter component that seems related)

For example, on the server side, structuring domain core by features is 
good thing (for me). Help define some boundaries and help maintability. 
Grouping all Java classes by technical aspect at the project root : all 
services in one package, all models in one package can be tedious.

On the front, if I correctly understood this thread :
- a unique Msg / Model inside Main.elm can be a good starting point and 
easy to refactor later. 
- separating the view per feature (only view functions) : advice taken from 
Dave
- break Model / Msg when too big (definition of "too big" is perhaps not 
easy, or someone can give some advices to detect "a too big Msg"). At this 
point, break Msg / Model / Update by feature. It is not all or nothing, 
just extract at first one feature and put them inside a file. Then the Main 
module wraps the feature (using map inside the Update).

Can we imagine starting a community guideline somewhere ? adding examples 
later.
Really easy for me to say that.


-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Structure for large Elm apps

2016-10-22 Thread Dave Thomas
Hi I wrote that article as a general overview of how I structured a single 
page app after reviewing different approaches, and relying on some of my 
knowledge of what worked for me in F# too.  Having the code structured in 
functions residing in modules made it really easy to update a specific part 
of the app, and also to refactor parts that needed it.  The hardest part 
was actually getting webpack to work with bootstrap4!


On Monday, October 17, 2016 at 7:41:23 PM UTC+1, Marcus Roberts wrote:
>
> Is this article (and the one it refers to) taking a good or bad approach 
> to program structure?
>
> http://7sharpnine.com/2016/10/03/building-an-spa-with-elm/
>
> I copied the structure as a way of seeing how a program might perhaps be 
> broken down, but it feels like a very component based approach, given each 
> level has its own update function.  I learnt a fair bit about mapping 
> between message types, so it was useful.
>
> I've broken my app down into pages using this structure, and so each page 
> has a view, model, etc.  Then the top level model has a model record for 
> each page.  This seems to work as it means the page doesn't need to know 
> how it's being used at the level above.  But the general conversations I 
> see suggests this is not the right way to go and to break things down more 
> into modules of related code.So I guess back to the original question, 
> is this structure a good way to work? 
>
>
>
>
> On Mon, Oct 17, 2016 at 7:50 AM, Peter Damoc  > wrote:
>
>> update is a function that takes a message and a model and produces the 
>> updated version of the model. In some cases, update also can produce some 
>> requests for more input (http requests, requests for random numbers, ports 
>> requests) this is why the top level update has (Model, Cmd Msg) as return. 
>> Internal updates however, might not need these requests and can be 
>> simpler. 
>> What you see in the repository you linked is a pattern of nesting 
>> "components" that is currently passively discouraged.  (there use to be a 
>> set of examples around this but they are gone). 
>>
>> The official recommendation around scaling is to focus on breaking the 
>> functionality into functions:
>> https://guide.elm-lang.org/reuse/
>>
>>
>>
>>
>> On Mon, Oct 17, 2016 at 12:00 AM, clouddie > > wrote:
>>
>>> Hi, are there official guidelines for structuring large scale apps ? For 
>>> instance, what is the community take on things like 
>>> https://github.com/rogeriochaves/structured-elm-todomvc/tree/modular ?
>>> This is quite neat although I cannot quite m'y head round the fact the 
>>> Update fonctions in TaskList deal with messages for Task ans TaskList, and 
>>> they do not respect thé standard (Model, Cmd Msg) signatures ?
>>>
>>> --
>>> 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...@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...@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] Structure for large Elm apps

2016-10-22 Thread Wouter In t Velt
Op vrijdag 21 oktober 2016 21:01:29 UTC+2 schreef Ed Ilyin:
>
> Can you, please, provide an example?
>

In a SPA I am developing, I use a structure like:
Helpers.elm
Helpers -- folder with more helpers
  Nav.elm -- helpers for navigation
  Exam.elm -- helpers for updating the exam
  Summaries.elm -- helpers (for view) to create a summary string from 
details
Main.elm
Model.elm
Msg.elm
Route.elm -- with routes the user can navigate to
Types.elm -- details of the stuff in the model
Update.elm
View.elm
Views -- folder with elm file per page, imported by view.elm
  Today.elm
  Exams.elm
  EditExam.elm
  PickExamDate.elm

Whenever I create a new page (let's say a page to see the entire calendar), 
I usually modify stuff in the following order:

   - add a route in Route.elm
   - add a type in Types.elm (if needed)
   - modify my Msg (if needed)
   - modify update.elm, 
   - add another view file in the view folder, 
   - and import this file in my main view.elm file.

Flat helps me to only change what is needed: Often a new page I want is 
just another view of the same data. So I do not need a new model, and I do 
not need to change the model, I only need a new view function. And a very 
simple change to the update function, to enable navigating to the new page.

I was very much inspired by the Time Tracker SPA (see here 
), which may also be a good place 
to look at a flat structure.

Previously, I had one exam component, with its own model, update and view. 
Each exam had a list of dates.
When I wanted to create a page that showed a calendar, and for each date, 
show the exams for which the user plans to study, I realised my component 
structure broke down.
-- before (nested)

type alias Model =
  { exams : List Exam }

type alias Exam =
  { subject : String
  , studyDates : List Date
  }

-- now (flat)

type alias Model =
  { exams : List Exam
  , studyDates : List StudyDate
  }

type alias Exam =
  { id : Int
  , subject : String
  }

type alias StudyDate =
  { studyDate : Date
  , exam : Int -- id only
  }

Hope this helps!

-- 
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] Structure for large Elm apps

2016-10-21 Thread Ed Ilyin
Can you, please, provide an example?
When I do a component (like one page of my SPA), I dedicate a module for
it. So, how can look a flat structure? Just Shared.elm, Main.elm,
Update.elm and View.elm?

Il giorno ven 21 ott 2016 alle ore 20:22 Wouter In t Velt <
wouter.intv...@gmail.com> ha scritto:

> +1 for the "better flat than nested " approach.
> I think it was the second elm town podcast where Brian admitted that he
> actually regretted his post.
>
> From personal experience (admittedly limited) I definitely agree to the
> "flat is better than nested". Having one update function with helpers, and
> not having any components with local state has made debugging at least 10x
> faster for me.
>
> Adding features like an undo function was way easier with a flat structure.
>
> --
> 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] Structure for large Elm apps

2016-10-21 Thread Wouter In t Velt
+1 for the "better flat than nested " approach.
I think it was the second elm town podcast where Brian admitted that he 
actually regretted his post.

>From personal experience (admittedly limited) I definitely agree to the "flat 
>is better than nested". Having one update function with helpers, and not 
>having any components with local state has made debugging at least 10x faster 
>for me.

Adding features like an undo function was way easier with a flat structure.

-- 
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] Structure for large Elm apps

2016-10-20 Thread clouddie
Actually, just to testify on nested components : got severely burnt by this 
pattern as I spent my Sunday refactoring my app before discovering that one 
nested component had to update the state of an other one, and realized I 
just did not want to go through the whole sibling or child whatever pattern 
(https://www.brianthicks.com/post/2016/06/27/candy-and-allowances-part-ii-child-child-communication-in-elm/)
 
which seems way too complicated.

So I just refactored out my main file into Model, Msg, Update, View, and 
used helper functions, and now my mind is clear again. "Better flat than 
nested" might be a good idea after all...

Le lundi 17 octobre 2016 21:38:14 UTC+2, Eric G a écrit :
>
> I'm no expert, and would like clarification on this as well, but "pages of 
> an app" seems like the main place where using nested modules makes sense -- 
> unless your pages can be modeled more easily as variants of each other, as 
> sometimes happens. 
>
> My experience* has been that just about everywhere else it's easier to 
> have flat modules, using helper update functions, view functions with 
> generic msg types, config records, etc., and extracting common bits as 
> needed into separate modules. Sometimes I have nested msg types, and do the 
> Html.App.map / Cmd.map  internally, within one module. Richard Feldman had 
> a list of "steps to take before breaking code out into separate modules" 
> awhile back that I thought was helpful.
>
> As for that article you linked to, it seems overkill, esp. for what is 
> mostly a static site. All of the static pages can just be functions in 
> Main, just split out the ones that have actual actions like the Contact 
> page, and then only if it seems unwieldy to handle those in Main too.  
>
> Basically my advice is start with Main, or Main and one page module, and 
> see how far you get, rather than planning ahead what your file structure is 
> going to look like.
>
> (*My experience is limited to business-y company-internal applications, 
> someone else will have to say what works for games and other kinds of 
> applications.)
>
>
> On Monday, October 17, 2016 at 2:41:23 PM UTC-4, Marcus Roberts wrote:
>>
>> Is this article (and the one it refers to) taking a good or bad approach 
>> to program structure?
>>
>> http://7sharpnine.com/2016/10/03/building-an-spa-with-elm/ 
>> 
>>
>> I copied the structure as a way of seeing how a program might perhaps be 
>> broken down, but it feels like a very component based approach, given each 
>> level has its own update function.  I learnt a fair bit about mapping 
>> between message types, so it was useful.
>>
>> I've broken my app down into pages using this structure, and so each page 
>> has a view, model, etc.  Then the top level model has a model record for 
>> each page.  This seems to work as it means the page doesn't need to know 
>> how it's being used at the level above.  But the general conversations I 
>> see suggests this is not the right way to go and to break things down more 
>> into modules of related code.So I guess back to the original question, 
>> is this structure a good way to work? 
>>
>>
>>
>>
>> On Mon, Oct 17, 2016 at 7:50 AM, Peter Damoc  wrote:
>>
>>> update is a function that takes a message and a model and produces the 
>>> updated version of the model. In some cases, update also can produce some 
>>> requests for more input (http requests, requests for random numbers, ports 
>>> requests) this is why the top level update has (Model, Cmd Msg) as return. 
>>> Internal updates however, might not need these requests and can be 
>>> simpler. 
>>> What you see in the repository you linked is a pattern of nesting 
>>> "components" that is currently passively discouraged.  (there use to be a 
>>> set of examples around this but they are gone). 
>>>
>>> The official recommendation around scaling is to focus on breaking the 
>>> functionality into functions:
>>> https://guide.elm-lang.org/reuse/
>>>
>>>
>>>
>>>
>>> On Mon, Oct 17, 2016 at 12:00 AM, clouddie  
>>> wrote:
>>>
 Hi, are there official guidelines for structuring large scale apps ? 
 For instance, what is the community take on things like 
 https://github.com/rogeriochaves/structured-elm-todomvc/tree/modular ?
 This is quite neat although I cannot quite m'y head round the fact the 
 Update fonctions in TaskList deal with messages for Task ans TaskList, and 
 they do not respect thé standard (Model, Cmd Msg) signatures ?

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

>>>
>>>
>>>
>>> -- 
>>> There is NO FATE

Re: [elm-discuss] Structure for large Elm apps

2016-10-17 Thread Eric G
I'm no expert, and would like clarification on this as well, but "pages of 
an app" seems like the main place where using nested modules makes sense -- 
unless your pages can be modeled more easily as variants of each other, as 
sometimes happens. 

My experience* has been that just about everywhere else it's easier to have 
flat modules, using helper update functions, view functions with generic 
msg types, config records, etc., and extracting common bits as needed into 
separate modules. Sometimes I have nested msg types, and do the 
Html.App.map / Cmd.map  internally, within one module. Richard Feldman had 
a list of "steps to take before breaking code out into separate modules" 
awhile back that I thought was helpful.

As for that article you linked to, it seems overkill, esp. for what is 
mostly a static site. All of the static pages can just be functions in 
Main, just split out the ones that have actual actions like the Contact 
page, and then only if it seems unwieldy to handle those in Main too.  

Basically my advice is start with Main, or Main and one page module, and 
see how far you get, rather than planning ahead what your file structure is 
going to look like.

(*My experience is limited to business-y company-internal applications, 
someone else will have to say what works for games and other kinds of 
applications.)


On Monday, October 17, 2016 at 2:41:23 PM UTC-4, Marcus Roberts wrote:
>
> Is this article (and the one it refers to) taking a good or bad approach 
> to program structure?
>
> http://7sharpnine.com/2016/10/03/building-an-spa-with-elm/ 
> 
>
> I copied the structure as a way of seeing how a program might perhaps be 
> broken down, but it feels like a very component based approach, given each 
> level has its own update function.  I learnt a fair bit about mapping 
> between message types, so it was useful.
>
> I've broken my app down into pages using this structure, and so each page 
> has a view, model, etc.  Then the top level model has a model record for 
> each page.  This seems to work as it means the page doesn't need to know 
> how it's being used at the level above.  But the general conversations I 
> see suggests this is not the right way to go and to break things down more 
> into modules of related code.So I guess back to the original question, 
> is this structure a good way to work? 
>
>
>
>
> On Mon, Oct 17, 2016 at 7:50 AM, Peter Damoc  > wrote:
>
>> update is a function that takes a message and a model and produces the 
>> updated version of the model. In some cases, update also can produce some 
>> requests for more input (http requests, requests for random numbers, ports 
>> requests) this is why the top level update has (Model, Cmd Msg) as return. 
>> Internal updates however, might not need these requests and can be 
>> simpler. 
>> What you see in the repository you linked is a pattern of nesting 
>> "components" that is currently passively discouraged.  (there use to be a 
>> set of examples around this but they are gone). 
>>
>> The official recommendation around scaling is to focus on breaking the 
>> functionality into functions:
>> https://guide.elm-lang.org/reuse/
>>
>>
>>
>>
>> On Mon, Oct 17, 2016 at 12:00 AM, clouddie > > wrote:
>>
>>> Hi, are there official guidelines for structuring large scale apps ? For 
>>> instance, what is the community take on things like 
>>> https://github.com/rogeriochaves/structured-elm-todomvc/tree/modular ?
>>> This is quite neat although I cannot quite m'y head round the fact the 
>>> Update fonctions in TaskList deal with messages for Task ans TaskList, and 
>>> they do not respect thé standard (Model, Cmd Msg) signatures ?
>>>
>>> --
>>> 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...@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...@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] Structure for large Elm apps

2016-10-17 Thread Marcus Roberts
Is this article (and the one it refers to) taking a good or bad approach to
program structure?

http://7sharpnine.com/2016/10/03/building-an-spa-with-elm/

I copied the structure as a way of seeing how a program might perhaps be
broken down, but it feels like a very component based approach, given each
level has its own update function.  I learnt a fair bit about mapping
between message types, so it was useful.

I've broken my app down into pages using this structure, and so each page
has a view, model, etc.  Then the top level model has a model record for
each page.  This seems to work as it means the page doesn't need to know
how it's being used at the level above.  But the general conversations I
see suggests this is not the right way to go and to break things down more
into modules of related code.So I guess back to the original question,
is this structure a good way to work?




On Mon, Oct 17, 2016 at 7:50 AM, Peter Damoc  wrote:

> update is a function that takes a message and a model and produces the
> updated version of the model. In some cases, update also can produce some
> requests for more input (http requests, requests for random numbers, ports
> requests) this is why the top level update has (Model, Cmd Msg) as return.
> Internal updates however, might not need these requests and can be
> simpler.
> What you see in the repository you linked is a pattern of nesting
> "components" that is currently passively discouraged.  (there use to be a
> set of examples around this but they are gone).
>
> The official recommendation around scaling is to focus on breaking the
> functionality into functions:
> https://guide.elm-lang.org/reuse/
>
>
>
>
> On Mon, Oct 17, 2016 at 12:00 AM, clouddie 
> wrote:
>
>> Hi, are there official guidelines for structuring large scale apps ? For
>> instance, what is the community take on things like
>> https://github.com/rogeriochaves/structured-elm-todomvc/tree/modular ?
>> This is quite neat although I cannot quite m'y head round the fact the
>> Update fonctions in TaskList deal with messages for Task ans TaskList, and
>> they do not respect thé standard (Model, Cmd Msg) signatures ?
>>
>> --
>> 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.
>

-- 
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] Structure for large Elm apps

2016-10-17 Thread clouddie
Hi, thanks for your answer, I also got the impression that component 
approach was being discouraged as the notorious "dual counters" and "list 
of counters" relying on the component approach have been withdrawn from 
documentation as it seems...

To be fair I have already read the docs, but my model, messages and update 
functions are becoming wy too unwieldy (> 1,000 lines), and Evan's 
footnote is not that helpful (I understand he must be the busiest man on 
earth) :

Note: I plan to fill this section in with more examples of growing your 
> Model and update functions. It is roughly the same ideas though. If you 
> find yourself repeating yourself, maybe break things out. If a function 
> gets too big, make a helper function. If you see related things, maybe move 
> them to a module. But at the end of the day, it is not a huge deal if you 
> let things get big. Elm is great at finding problems and making refactors 
> easy, so it is not actually a huge deal if you have a bunch of entries in 
> your Model because it does not seem better to break them out in some way. 
> I will be writing more about this!


 

Le lundi 17 octobre 2016 08:50:23 UTC+2, Peter Damoc a écrit :
>
> update is a function that takes a message and a model and produces the 
> updated version of the model. In some cases, update also can produce some 
> requests for more input (http requests, requests for random numbers, ports 
> requests) this is why the top level update has (Model, Cmd Msg) as return. 
> Internal updates however, might not need these requests and can be 
> simpler. 
> What you see in the repository you linked is a pattern of nesting 
> "components" that is currently passively discouraged.  (there use to be a 
> set of examples around this but they are gone). 
>
> The official recommendation around scaling is to focus on breaking the 
> functionality into functions:
> https://guide.elm-lang.org/reuse/
>
>
>
>
> On Mon, Oct 17, 2016 at 12:00 AM, clouddie  > wrote:
>
>> Hi, are there official guidelines for structuring large scale apps ? For 
>> instance, what is the community take on things like 
>> https://github.com/rogeriochaves/structured-elm-todomvc/tree/modular ?
>> This is quite neat although I cannot quite m'y head round the fact the 
>> Update fonctions in TaskList deal with messages for Task ans TaskList, and 
>> they do not respect thé standard (Model, Cmd Msg) signatures ?
>>
>> --
>> 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...@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.


Re: [elm-discuss] Structure for large Elm apps

2016-10-16 Thread Peter Damoc
update is a function that takes a message and a model and produces the
updated version of the model. In some cases, update also can produce some
requests for more input (http requests, requests for random numbers, ports
requests) this is why the top level update has (Model, Cmd Msg) as return.
Internal updates however, might not need these requests and can be simpler.
What you see in the repository you linked is a pattern of nesting
"components" that is currently passively discouraged.  (there use to be a
set of examples around this but they are gone).

The official recommendation around scaling is to focus on breaking the
functionality into functions:
https://guide.elm-lang.org/reuse/




On Mon, Oct 17, 2016 at 12:00 AM, clouddie 
wrote:

> Hi, are there official guidelines for structuring large scale apps ? For
> instance, what is the community take on things like https://github.com/
> rogeriochaves/structured-elm-todomvc/tree/modular ?
> This is quite neat although I cannot quite m'y head round the fact the
> Update fonctions in TaskList deal with messages for Task ans TaskList, and
> they do not respect thé standard (Model, Cmd Msg) signatures ?
>
> --
> 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.