What is this really about?
Is it about performance?
Do you have bad performance and are thinking that if this would be
available you will get better performance?
Because if this is the case, you could try to create a SSCCE of this bad
performance and we could take a look and come up with some solutions.
What I understood from your request looks like you want smarter
functionality when this could be achieved with smarter data structures.
If you have a lot of NoOp littering your code, think harder about your
structures.
I doubt that a solution like what you are proposing will not make the code
look better, it might just replace the NoOp with States.noChanges.
You could have your model split in two with one part holding data that is
essential to the view and another part holding accidental data.
You could then have your main view like:
view : Model -> Html Msg
view model =
lazy mainView model.essential
you could have the update split the same
type Msg = Essential EssentialMsg | BookKeeping BookKeepingMsg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Essential eMsg ->
let
(newEssential, cmd) =
updateEssential eMsg model.essential
in
({model | essential = newEssential}, cmd)
BookKeeping bMsg ->
let
(newBookKeeping, cmd) =
updateBookKeeping bMsg model.bookKeeping
in
({model | bookKeeping = newBookKeeping}, cmd)
And this is just one of your already available options.
If you like the blah pattern, you can even implement it as a decorator for
the App.program and keep flags and what not in some model together with the
user model.
You have this freedom with the current functionality.
If there is however an issue of performance that would really be made much
better by some changes to the core, then this needs to come with a SSCCE
and detailed analysis.
On Mon, Aug 8, 2016 at 10:20 PM, OvermindDL1 <[email protected]> wrote:
> For note, current work-arounds to lacking the above are things like:
>
> - Handling each no-op messages in the update itself, I have a lot of
> matching cases with no-op `( model, Cmd.none )` all over the place, it is
> ugly and useless
> - Various simplifiers in your own code that convert:
> ```elm
> Helpers helpersMsg ->
> let
> ( helpersModel, helpersCmd ) =
> helpers_update Helpers helpersMsg model.helpers
> in
> ( { model | helpers = helpersModel }
> , helpersCmd
> )
> ```
> Into this:
> ```elm
> Helpers helpersMsg ->
> convertToMyModel
> (\newModel -> { model | helpers=newModel } )
> ( helpers_update Helpers helpersMsg model.helpers )
> ```
> Which although shorter and more re-useable is also more unreadable
> (especially due to the lack of something like `put .helpers model`, I would
> love to know if someone knows a workaround for that, which is shorter and
> more readable than `(\newModel -> { model | helpers=newModel } )`)
> - Also do not have to add other TEA module subscriptions to your
> subscriptions, which although a bonus is not a biggie.
>
> Much of this could be done via helper libraries that are hooked before
> update and subscriptions the view is not so easy to work-around without the
> internal library keeping a copy of the view around for when the view does
> not want to be called and it could just return it straight, that could
> potentially be quite large to be holding another copy of, but it could be
> done 'for now' as an example package implementation.
>
>
>
> On Monday, August 8, 2016 at 1:12:00 PM UTC-6, OvermindDL1 wrote:
>>
>> It would be highly useful if there was a way to prevent view,
>> subscription, or update from being called while also allowing for module
>> transformation for TEA/following modules, which could all be handled via
>> adding a single callback (described below) to Program (or a new version
>> there-of). It would require a simple change to the core javascript native
>> code (linked below). Just having Html.lazy on the top view itself is
>> insufficient as it does not handle being able to prevent update calls (say
>> if the model does not change and no command is raised, useful for view
>> update, a rare case and could be ignored in general), being able to prevent
>> or filter subscriptions (highly important in many cases, this would allow
>> for ignore certain subscription messages, say you are handling input and do
>> not want to listen to certain keys or only want to listen to certain keys
>> then this would allow you to handle both filtering it as well as
>> translating the the filtered data into a new message if wanted all in one
>> step), as well as also preventing view updates on a variety of model
>> updates (ways that lazy fails badly in is if you are receiving a stream of
>> messages from a server, each one is causing a view update, when they are
>> incoming as a singular stream and you know when it stops and can turn back
>> 'on' rendering at that point, thus completely ignore the view updates for
>> the given message stream Message and leave it on for everything else). You
>> could potentially nest lazy's only matching on specific criteria and a
>> model variable to define whether it is on or not, but then you have to make
>> sure you always turn it on on message types that handle views and turn it
>> off only for your specific one, when that really should both be reversed in
>> structure and should have no state variable. Such a callback could also
>> handle module transformation for TEA styled handling.
>>
>> Thus for the new callback I propose is something like this, called `blah`
>> for now since I am bad with naming and do not want to pre-dispose an idea
>> of how it should work based on the name:
>> ```elm
>>
>> module main exposing (..)
>> main : Program ProgramFlagsmain =
>> App.programWithFlags
>> { init = init
>> , blah = blah
>> , view = view
>> , update = update
>> , subscriptions = subscriptions
>> }
>> -- Snip other callback code as they are unchanged
>> blah : Msg -> ( Msg, States )blah msg =
>> case msg of
>> MyMessageThree _ -> ( msg, States.batch [ States.cancelView,
>> States.cancelSubscriptions ) -- Just preventing certain callbacks
>> MyMessageNine arg0 _ -> ( MyMessageThree arg0, States.all ) -- -- Just
>> converting a message to another
>> MyRedrawMessage -> ( msg, States.onlyView ) -- Just redraw the view,
>> unsure if necessary but it is here for completion.
>> MyMessageTwelve _ -> ( msg, States.onlyUpdate ) -- Just handle an
>> update, subscriptions and view are not called
>> OnKeyPress 13 -> ( msg, States.none ) -- Cancel every callback when
>> OnKeyPress's value is 13, else it will fall back to the default lower of _
>> that passes through everything unchanged
>> OnKeyPress 119 -> ( MoveUp, States.all) -- Convert this specific
>> OnKeyPress into a MoveUp message instead, the OnKeyPress vanishes
>> MaterialMessage msg -> Material.blah .mdl (\model newMdl -> { model |
>> mdl=newMdl } ) msg
>> _ -> ( msg, States.noChanges )
>>
>> -- Material.blah could be implemented likemodule Material
>> blah : ( model -> Material.Model ) -> ( model -> Material.Model -> model )
>> -> Material.Msg -> ( Msg, States )blah getModel putModel msg =
>> ( msg
>> , States.delegate
>> { getModel=getModel
>> , putModel=putModel
>> , update=Material.update
>> , subscriptions=Material.subscriptions
>> }
>> )
>>
>> ```
>>
>> As you can see it allows but is not restricted to:
>>
>> - Message translation
>> - Callback cancellation
>> - Message filtering
>> - Message filtering and translation
>> - TEA models direct update/subscriptions conversion (Just like how
>> you can do `.mdl model` to get `model.mdl`, I wish there were a way to do
>> something like `put .mdl model something` and it does `{ model | mdl =
>> something }`, it would make that last second callback more simple)
>> - <salesman-voice>And more!
>>
>> This solves a variety of issues in but not restricted to:
>>
>> - Simplifying the update to only handle what is actually important
>> - Calling view at all only when it is needed (letting you not call it
>> on hot-path messages for example, like when getting a thousand messages to
>> fill in something but you don't want to render it until the stream is
>> complete)
>> - TEA style inclusion of other modules in a central-include point
>> without needing to pepper crap like this all over your update and more:
>> ```elm
>>
>> Helpers helpersMsg ->
>> let
>> ( helpersModel, helpersCmd ) =
>> helpers_update Helpers helpersMsg model.helpers
>> in
>> ( { model | helpers = helpersModel }
>> , helpersCmd
>> )
>>
>> ```
>>
>>
>>
>>
>> This is my prior post about this:
>>
>> I do say that I wish there were some way to make some 'update' call as
>> no-view and/or no-subscription re-call needed. Like instead of returning
>> `( model, Cmd.none )` we could do `( model, Cmd.cancelView )` or `( model,
>> Cmd.cancelSubscription )` or both via `Cmd.batch`, or perhaps as a
>> three-argument tuple that defaults to `( model, Cmd.none, StateChanges.none
>> )` or so, which would default to calling everything. I have a lot of
>> update messages that are handled that do not change the view and/or
>> subscriptions and it would be nice to prevent calling those somehow. Hmm,
>> actually a backward compatible change would be to add a new Program
>> callback, in addition to the usual `init`, `update`, `subscriptions`, and
>> `view`, add another one that I will call just `blah` for now, optional in
>> the Program or so, but have it be like:
>> ```
>> blah : Msg -> ( Msg, States )
>> blah msg ->
>> case msg of
>> MyMessageThree _ -> ( msg, States.batch [ States.cancelView,
>> States.cancelSubscriptions )
>> MyMessageNine arg0 _ -> ( MyMessageThree arg0, States.noChanges ) --
>> or `States.none`?
>> MyRedrawMessage -> ( msg, States.cancelView )
>> MyMessageTwelve _ -> ( msg, States.onlyUpdate )
>> _ -> ( msg, States.noChanges )
>> ```
>>
>> And it would be called after `init` and before every call of `update`.
>> It would allow an easy way to translate one message type into another
>> (maybe even a way to decorate it more so it can get passed to another
>> modules update/subscription, this would be a **great** hooking location for
>> modules), as well as a way to specify what states should be updated for a
>> given message, a default no-op function could be supplied via
>> `States.defaultHandle` or so that you could pass to the program so people
>> do not have to override it in the easy cases.
>>
>> Hmm, an idea for a module handler, one of the states could be something
>> like:
>> ```elm
>> MaterialMessage msg -> ( msg, States.delegate {
>> update=Material.update, subscriptions=Material.subscriptions } )
>> ```
>> Which of course the other module could simplify via a helper to:
>> ```elm
>> MaterialMessage msg -> Material.blah msg
>> ```
>>
>> Looking at https://github.com/elm-lang/core/blob/4.0.4/src/Native/Platf
>> orm.js shows that it would be easy to add that functionality to core.
>>
>> So ideas about this style, issues, etc...?
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.