Re: [elm-discuss] Re: Html.Keyed

2016-10-15 Thread OvermindDL1
On Wednesday, October 12, 2016 at 5:32:09 AM UTC-6, Max Froumentin wrote:
>
> Thanks OvermindDL1, that's very helpful. I now understand it's down to the 
> lack of two-way binding. Makes sense.
> Wouldn't it be useful to use a change of id attribute as a change of key?
>

Yep, adding an attribute ID of some sort would make that 'more expected', 
and some vdom libraries do indeed do that (that I could link you to if you 
are curious at seeing the implementation).  :-) 

On Wednesday, October 12, 2016 at 9:59:47 AM UTC-6, Mark Hamburg wrote:
>
> On Oct 11, 2016, at 1:09 PM, OvermindDL1  wrote: 
> > 
> > And as for cocoa, unlike the DOM anytime something like, say a checkbox 
> is checked, cocoa sends a message to the application to handle the change, 
> if unhandled then no update would happen... and the app would be frozen as 
> the event loop would not be processing, unlike the DOM in a browser that 
> would just keep on puttering along even if no handlers for any events were 
> registered in javascript at all.  They are entirely different programming 
> domains. 
>
> Actually, no, with respect to Cocoa. If a Cocoa view sends out a message 
> that the value changed, the controller is not required or even expected to 
> echo that change back. The message can disappear into the aether and the 
> state will remain. (Caveat: It's been a while since I've coded against the 
> Cocoa APIs.) So, it is essentially an identical situation of there being 
> extra state that is tied to the existence of a Cocoa view object or a DOM 
> element.


This is indeed true that you do not need to handle it, however you still 
need to `pump` the message loop so, in elm terminology, it gets processed 
to the right effect manager (in reality when the message loop gets pumped 
anything listening to the messages can react as you wish, but you yourself 
still have to pump it, although that code is generally already set up for 
you via the normal scaffolds, but it is very explicit where elm is more 
implicit and magical). 

On Thursday, October 13, 2016 at 2:20:36 PM UTC-6, Rupert Smith wrote:

By making it keyed then it is like "oh, these do not match at all, probably 
> a major structural change, kill the old, create the new".
>

I have to admit I am not really sure how Html.Keyed works, so this is an 
illuminating discussion for me. Could you answer some basic questions about 
it for me?

If the 'key' of a keyed node is the same, is it never updated?
If 'key' of a keyed node changes, is the whole node built anew?

Or something else, please explain it to me, thanks.


In Elm if a 'keyed node'  is changed then it will diff as normal.  If a 
keyed node has an ID change then it tests the node before and after in the 
old version and shuffles around as necessary (only 1 at a time, larger 
jumps cause destroy/recreations), and if none nearby match then it entirely 
destroys or creates it as necessary.  I went a different route with my VDom 
but I'm still unsure about my style, though it does work well and gets rid 
of the keyed node and lazy node concepts in a larger singular super-node 
thing...

On Thursday, October 13, 2016 at 2:23:04 PM UTC-6, Rupert Smith wrote:

Some other questions relating to this.

I have a node that I changed an Html.Attribute.property on. The node had 2 
properties, but I only changed one. However, the node as a webcomponent 
fired triggered an observer on the other property that was not changed.

If I change just one property of a node, are all properties updated?

What about atttributes, if I change one attribute are all updated?


Uh, it should not do that I would think, sounds like a bug as an un-touched 
attribute should not be touched.  Unsure if Elm or the 
webcomponent-library-that-you-are-using kind of bug, but it sounds like a 
bug (I'd wager in the webcomponent polyfill you are using most likely, does 
sound weird...).

-- 
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: Element continuity (was Re: [elm-discuss] Re: Html.Keyed)

2016-10-14 Thread Mark Hamburg
Actually, the existing documentation for Html.Keyed comes close to saying what 
needs to be said:

> Works just like Html.node, but you add a unique identifier to each child 
> node. You want this when you have a list of nodes that is changing: adding 
> nodes, removing nodes, etc. In these cases, the unique identifiers help make 
> the DOM modifications more efficient.

In addition to make the modifications more efficient, it makes them more 
correct because it avoids having positional shifts cause confusion.

Basic rule: If the set of children for an Html node can change, then you should 
use Html.Keyed for that node to avoid problems with DOM element state or focus.

Side note: Do not reuse keys under a node if you don't want state preserved. 
(That's the issue that started the parent thread.)

Mark

-- 
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: Html.Keyed

2016-10-13 Thread 'Rupert Smith' via Elm Discuss
On Thursday, October 13, 2016 at 9:20:36 PM UTC+1, Rupert Smith wrote:
>
> On Tuesday, October 11, 2016 at 9:09:31 PM UTC+1, OvermindDL1 wrote:
>>
>> Remember, it is just a diffing algorithm, when it gets to that point of 
>> your vdom and it compares an old vdom node of, for example:
>> ```
>>   checkbox [ onClick (CheckToggle 42) ] [ text "Something" ]
>> ```
>> and compares it to the new of:
>> ```
>>   checkbox [ onClick (CheckToggle 43) ] [ text "Another thing" ]
>> ```
>> It sees that there are two changes (well potentially 1 due to lack of 
>> keyed event handlers, but we'll say 2 for this example), thus it accesses 
>> the checkbox at the index that it is at here (say, 14 or so) by just 
>> something like `var node = curNode.children[14];` then just applies the 
>> two changes `node.removeEventHandler("click", oldEvent); 
>> node.addEventHandler("click", newEvent); node.children[0].nodeValue = 
>> "Another thing";`, which was just removing the old event handler, adding 
>> the new, and mutating the text.
>>
>  
> Interesting to see this expained, thanks.
>

Some other questions relating to this.

I have a node that I changed an Html.Attribute.property on. The node had 2 
properties, but I only changed one. However, the node as a webcomponent 
fired triggered an observer on the other property that was not changed.

If I change just one property of a node, are all properties updated?

What about atttributes, if I change one attribute are all updated?

Thanks.

-- 
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: Html.Keyed

2016-10-13 Thread 'Rupert Smith' via Elm Discuss
On Tuesday, October 11, 2016 at 9:09:31 PM UTC+1, OvermindDL1 wrote:
>
> Remember, it is just a diffing algorithm, when it gets to that point of 
> your vdom and it compares an old vdom node of, for example:
> ```
>   checkbox [ onClick (CheckToggle 42) ] [ text "Something" ]
> ```
> and compares it to the new of:
> ```
>   checkbox [ onClick (CheckToggle 43) ] [ text "Another thing" ]
> ```
> It sees that there are two changes (well potentially 1 due to lack of 
> keyed event handlers, but we'll say 2 for this example), thus it accesses 
> the checkbox at the index that it is at here (say, 14 or so) by just 
> something like `var node = curNode.children[14];` then just applies the 
> two changes `node.removeEventHandler("click", oldEvent); 
> node.addEventHandler("click", newEvent); node.children[0].nodeValue = 
> "Another thing";`, which was just removing the old event handler, adding 
> the new, and mutating the text.
>
 
Interesting to see this expained, thanks.

By making it keyed then it is like "oh, these do not match at all, probably 
> a major structural change, kill the old, create the new".
>

I have to admit I am not really sure how Html.Keyed works, so this is an 
illuminating discussion for me. Could you answer some basic questions about 
it for me?

If the 'key' of a keyed node is the same, is it never updated?
If 'key' of a keyed node changes, is the whole node built anew?

Or something else, please explain it to me, thanks.

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


Element continuity (was Re: [elm-discuss] Re: Html.Keyed)

2016-10-12 Thread Mark Hamburg
On Oct 11, 2016, at 1:09 PM, OvermindDL1  wrote:
> 
> And as for cocoa, unlike the DOM anytime something like, say a checkbox is 
> checked, cocoa sends a message to the application to handle the change, if 
> unhandled then no update would happen... and the app would be frozen as the 
> event loop would not be processing, unlike the DOM in a browser that would 
> just keep on puttering along even if no handlers for any events were 
> registered in javascript at all.  They are entirely different programming 
> domains.

Actually, no, with respect to Cocoa. If a Cocoa view sends out a message that 
the value changed, the controller is not required or even expected to echo that 
change back. The message can disappear into the aether and the state will 
remain. (Caveat: It's been a while since I've coded against the Cocoa APIs.) 
So, it is essentially an identical situation of there being extra state that is 
tied to the existence of a Cocoa view object or a DOM element.

The problem this poses for all render-and-diff-based virtual DOM systems — and 
you are correct that React shouldn't be immune — is that the diffing algorithm 
has to infer when to keep using an existing element and when to create a new 
element. The only truly reliable way around that would be to require attaching 
unique identifiers to rendered nodes that the diff algorithm to use to 
recognize continuity and that's messy in broader practice (though see below). 
That said, that's exactly what Html.Keyed does so if there is a problem here it 
isn't in Html.Keyed but rather in the documentation around how the virtual DOM 
relates to the physical DOM and how in particular that plays out for Html.Keyed.

What should perhaps be more worrisome is that the render-and-diff algorithm can 
produce different results depending on how often we render. Render frequently 
and maybe an element goes away and then a new element gets created. Render 
infrequently and maybe the existing element gets reused. Html.Keyed can be used 
to work around this by using a new key to force creation but again 
understanding that work around takes understanding the relationship between the 
virtual and physical DOM at a deeper level than the documentation for Elm (or 
React?) tends to cover. (For those who are a bit performance obsessed, 
Html.Keyed also has the annoyance of introducing an extra div element, but 
that's just a niggle.)

The work on web components touches on this issue as well. The point to using 
web components is often to allow them to encapsulate private state but then we 
need to manage the lifetime for that private state.

This really comes down to a question of managing when the DOM diff algorithm 
should consider two elements the same and when it shouldn't. As noted, we could 
simply require that all elements have unique ID's and continuity would be based 
on ID equality but then we would have the problem of managing a global ID 
space. Not wanting to go there, let's look at what we've got available:

* Normal nodes manage their children positionally. This should argue for 
treating such nodes as always having a fixed set of children and the DOM diff 
algorithm could complain when they don't noting that changing the set of 
children introduces risks that the diff algorithm will make the wrong choice or 
will miss a change by not running often enough. (There are also risks if 
children change their kind because if the change is seen it will result in 
element destruction and creation and if it is not seen because the kind changes 
back, it will likely result in element reuse.)

* Keyed nodes manage their children based on keys. These work well for identity 
provided one understands the implications of that identity. Keyed nodes can be 
used for lists but also for forced destruction and creation of DOM elements.

What seems like it bears some further investigation is looking at more ways to 
use keyed nodes to manage non-homogenous lists, changeable lists of sub-views.

Another interesting point to investigate would be debugging tools that compare 
the number of elements created and destroyed depending on how often the 
render-and-diff algorithm is run.

Mark

-- 
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: Html.Keyed

2016-10-12 Thread Max Froumentin
Thanks OvermindDL1, that's very helpful. I now understand it's down to the 
lack of two-way binding. Makes sense.
Wouldn't it be useful to use a change of id attribute as a change of key?


On Tuesday, October 11, 2016 at 6:11:15 PM UTC+1, OvermindDL1 wrote:
>
> The ticked checkbox is because the user ticked it, it is some of the 
> implicit DOM state.  When the view changed to remove a checkbox but it 
> still had another one after, since they were not keyed it just did a 'diff' 
> between states.  The vdom has no information on any implicit state in the 
> actual DOM, in fact it does not access the actual DOM at all except to 
> apply patches, thus when it saw from its point of view that the checkbox 
> label had its name changed but nothing else different about it then it sent 
> a patch to change the text and that is all.  By changing the 'key' of it 
> then it knows that it is an entire tree change and will not even attempt a 
> patch but will instead rather re-generate the entire tree.
>
> Basically if a tree were to be regenerated just because some text changed 
> than that would make a virtual-dom extremely slow, its whole point is only 
> to generate a set of differences between two virtual-doms and apply those 
> differences to the real dom without ever reading anything from the real dom 
> (as that is very slow).
>
> It would indeed be preferable for checked-state to be controlled 
> exclusively via the model and view, however only an event is sent for those 
> changes and there is no way for the vdom to update its internal information 
> otherwise, and registering an event everywhere, even bubbled events, would 
> again make the vdom very slow and force the user to have to handle a lot of 
> extra cases (imagine checked state, text values, even focus and all being 
> controlled like this).
>
>
> On Tuesday, October 11, 2016 at 11:01:57 AM UTC-6, Max Froumentin wrote:
>>
>> Hi there,
>>
>> Today I raised https://github.com/elm-lang/virtual-dom/issues/37
>> Given there's no consensus on whether it's a bug, I'm bringing the 
>> discussion here.
>>
>> The reason why I think it's a bug is that the second time the view 
>> function runs it generates a ticked checkbox, although nowhere in the view 
>> function is there any indication that a ticked checkbox should be generated.
>>
>> The alternative view is that the checkbox that's been clicked on has only 
>> been mutated with new data. That's why it remains ticked. You need to use 
>> Html.Keyed to tell elm that it is an entirely new checkbox.
>>
>> I must say I'm not convinced why the view function should generate Html 
>> that depends on the previous state of the model.
>>
>> Thanks for any insight.
>>
>>

-- 
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: Html.Keyed

2016-10-11 Thread OvermindDL1
Eh, not really, it is precisely the same issues as you would have with, for 
example, React, or any of the other JS libraries that use virtual-doms. 
 Just an aspect of how web browser DOM's are made due to backwards 
compatibility with a lot of old sites over a period of many many decades. 
 Have to know about the platform that is being programmed for is all, this 
is not Elm specific.  :-)

Remember, it is just a diffing algorithm, when it gets to that point of 
your vdom and it compares an old vdom node of, for example:
```
  checkbox [ onClick (CheckToggle 42) ] [ text "Something" ]
```
and compares it to the new of:
```
  checkbox [ onClick (CheckToggle 43) ] [ text "Another thing" ]
```
It sees that there are two changes (well potentially 1 due to lack of keyed 
event handlers, but we'll say 2 for this example), thus it accesses the 
checkbox at the index that it is at here (say, 14 or so) by just something 
like `var node = curNode.children[14];` then just applies the two changes 
`node.removeEventHandler("click", 
oldEvent); node.addEventHandler("click", newEvent); 
node.children[0].nodeValue = "Another thing";`, which was just removing the 
old event handler, adding the new, and mutating the text.  Notice that it 
did not set the checked value because you never said what the checked value 
should be (thus meaning there was no difference in your defined checked 
state, thus it just leaves it at whatever it was since it sees no change to 
apply).

By making it keyed then it is like "oh, these do not match at all, probably 
a major structural change, kill the old, create the new".

If instead it did, as you imply, the deleting of the checkbox and 
recreating it so it has a consistent state regardless, then that would be 
an absolutely monstrous amount of DOM manipulating for, say, just a tiny 
text change, thus entirely defeating the point of a differencing system 
like a virtual dom (of which the sole purpose of is for speed), while also 
causing things like the checkbox to uncheck any time anything near its 
point on the DOM changed even by a single character in a text node.  :-)

If, however, you defined what the checked state should be in the vdom, then 
it would see that the old was checked, and the new was not, and would 
remove that property of it.  :-)


And as for cocoa, unlike the DOM anytime something like, say a checkbox is 
checked, cocoa sends a message to the application to handle the change, if 
unhandled then no update would happen... and the app would be frozen as the 
event loop would not be processing, unlike the DOM in a browser that would 
just keep on puttering along even if no handlers for any events were 
registered in javascript at all.  They are entirely different programming 
domains.

Some setups, like Angular 1, used two-way binding to overcome these issues, 
so the DOM could be reflected back in to the data model, however that is 
both hard to model and incurs significant speed hits based on access 
patterns (hence why Angular 2 got rid of it as I recall, though not messed 
with it to know for sure).


On Tuesday, October 11, 2016 at 1:33:38 PM UTC-6, Mark Hamburg wrote:
>
> I haven't yet dug into the actual example code, but this response goes 
> straight to the issue of continuity of identity that makes things like web 
> components an interesting problem for a functional virtual DOM.
>
> Mark
>
> P.S. I prototyped a system a few years ago on Cocoa in which view creation 
> was explicit — thereby providing identity — but property updates after 
> creation all came from reactive signals. It worked pretty well but took 
> more thought to use than does Elm's "just re-render the tree as you want 
> it" approach. What we're seeing here is that without identity — or with 
> erroneous identity — the diff the vdoms approach can have its own serious 
> surprises.
>
> On Oct 11, 2016, at 10:11 AM, OvermindDL1  > wrote:
>
> The ticked checkbox is because the user ticked it, it is some of the 
> implicit DOM state.  When the view changed to remove a checkbox but it 
> still had another one after, since they were not keyed it just did a 'diff' 
> between states.  The vdom has no information on any implicit state in the 
> actual DOM, in fact it does not access the actual DOM at all except to 
> apply patches, thus when it saw from its point of view that the checkbox 
> label had its name changed but nothing else different about it then it sent 
> a patch to change the text and that is all.  By changing the 'key' of it 
> then it knows that it is an entire tree change and will not even attempt a 
> patch but will instead rather re-generate the entire tree.
>
> Basically if a tree were to be regenerated just because some text changed 
> than that would make a virtual-dom extremely slow, its whole point is only 
> to generate a set of differences between two virtual-doms and apply those 
> differences to the real dom without ever reading anything from the real 

Re: [elm-discuss] Re: Html.Keyed

2016-10-11 Thread Mark Hamburg
I haven't yet dug into the actual example code, but this response goes straight 
to the issue of continuity of identity that makes things like web components an 
interesting problem for a functional virtual DOM.

Mark

P.S. I prototyped a system a few years ago on Cocoa in which view creation was 
explicit — thereby providing identity — but property updates after creation all 
came from reactive signals. It worked pretty well but took more thought to use 
than does Elm's "just re-render the tree as you want it" approach. What we're 
seeing here is that without identity — or with erroneous identity — the diff 
the vdoms approach can have its own serious surprises.

> On Oct 11, 2016, at 10:11 AM, OvermindDL1  wrote:
> 
> The ticked checkbox is because the user ticked it, it is some of the implicit 
> DOM state.  When the view changed to remove a checkbox but it still had 
> another one after, since they were not keyed it just did a 'diff' between 
> states.  The vdom has no information on any implicit state in the actual DOM, 
> in fact it does not access the actual DOM at all except to apply patches, 
> thus when it saw from its point of view that the checkbox label had its name 
> changed but nothing else different about it then it sent a patch to change 
> the text and that is all.  By changing the 'key' of it then it knows that it 
> is an entire tree change and will not even attempt a patch but will instead 
> rather re-generate the entire tree.
> 
> Basically if a tree were to be regenerated just because some text changed 
> than that would make a virtual-dom extremely slow, its whole point is only to 
> generate a set of differences between two virtual-doms and apply those 
> differences to the real dom without ever reading anything from the real dom 
> (as that is very slow).
> 
> It would indeed be preferable for checked-state to be controlled exclusively 
> via the model and view, however only an event is sent for those changes and 
> there is no way for the vdom to update its internal information otherwise, 
> and registering an event everywhere, even bubbled events, would again make 
> the vdom very slow and force the user to have to handle a lot of extra cases 
> (imagine checked state, text values, even focus and all being controlled like 
> this).
> 
> 
>> On Tuesday, October 11, 2016 at 11:01:57 AM UTC-6, Max Froumentin wrote:
>> Hi there,
>> 
>> Today I raised https://github.com/elm-lang/virtual-dom/issues/37
>> Given there's no consensus on whether it's a bug, I'm bringing the 
>> discussion here.
>> 
>> The reason why I think it's a bug is that the second time the view function 
>> runs it generates a ticked checkbox, although nowhere in the view function 
>> is there any indication that a ticked checkbox should be generated.
>> 
>> The alternative view is that the checkbox that's been clicked on has only 
>> been mutated with new data. That's why it remains ticked. You need to use 
>> Html.Keyed to tell elm that it is an entirely new checkbox.
>> 
>> I must say I'm not convinced why the view function should generate Html that 
>> depends on the previous state of the model.
>> 
>> Thanks for any insight.
> 
> -- 
> 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: Html.Keyed

2016-10-11 Thread OvermindDL1
The ticked checkbox is because the user ticked it, it is some of the 
implicit DOM state.  When the view changed to remove a checkbox but it 
still had another one after, since they were not keyed it just did a 'diff' 
between states.  The vdom has no information on any implicit state in the 
actual DOM, in fact it does not access the actual DOM at all except to 
apply patches, thus when it saw from its point of view that the checkbox 
label had its name changed but nothing else different about it then it sent 
a patch to change the text and that is all.  By changing the 'key' of it 
then it knows that it is an entire tree change and will not even attempt a 
patch but will instead rather re-generate the entire tree.

Basically if a tree were to be regenerated just because some text changed 
than that would make a virtual-dom extremely slow, its whole point is only 
to generate a set of differences between two virtual-doms and apply those 
differences to the real dom without ever reading anything from the real dom 
(as that is very slow).

It would indeed be preferable for checked-state to be controlled 
exclusively via the model and view, however only an event is sent for those 
changes and there is no way for the vdom to update its internal information 
otherwise, and registering an event everywhere, even bubbled events, would 
again make the vdom very slow and force the user to have to handle a lot of 
extra cases (imagine checked state, text values, even focus and all being 
controlled like this).


On Tuesday, October 11, 2016 at 11:01:57 AM UTC-6, Max Froumentin wrote:
>
> Hi there,
>
> Today I raised https://github.com/elm-lang/virtual-dom/issues/37
> Given there's no consensus on whether it's a bug, I'm bringing the 
> discussion here.
>
> The reason why I think it's a bug is that the second time the view 
> function runs it generates a ticked checkbox, although nowhere in the view 
> function is there any indication that a ticked checkbox should be generated.
>
> The alternative view is that the checkbox that's been clicked on has only 
> been mutated with new data. That's why it remains ticked. You need to use 
> Html.Keyed to tell elm that it is an entirely new checkbox.
>
> I must say I'm not convinced why the view function should generate Html 
> that depends on the previous state of the model.
>
> Thanks for any insight.
>
>

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