Behavioural issues
An update to a signal that is part of a loop is propagated but does not cause that same signal to update again on its own. That's the behaviour a standard loop should have I think... It's what I'm after for the game example anyway, and I thought about that loop without thinking hard, more relying on intuition. Loop behaviour may be confusing for a newbies, so using naive intuition as a possible definition for the behaviour seems like a start...
There are some problems hidden in the details of the behaviour of the envisioned loop. Imagine a loop like this:
First, do we (for example) specify the starting value for o1 and then calculate the values of o2 and o3 from the functions and the signal source defaults? Do we recalculate o1 from this too and then stop?
The next problem: say we get the situation that i1 changes to the value 2, and the others stay the same. o1 obviously changes to what o3 was with 2 prepended to it. But now what do we do with o2 and o3? Do they just get an extra 2 and 3 prepended? And if they don't change, how would you implement that in general?
Then the final problem: what if two signals change at the same time? Which change goes first? Or does it not make sense to do this deterministic? I personally prefer it... But it's hard, especially when you consider a runtime system in which every f is a separate thread and the signals are actual queues with messages.
My brain answered me these questions with a headache, so I hope I'm not giving you one too...
I did think in the direction of not considering all parts of the equal. You can't write it that way in code anyway. So instead look at the circular signal as an actual signal, look at it as a linear thing with a special loop-back part:
Does this depiction inspire you to a good idea of how this should behave? I hope so, because whatever I thought was handy about looking at it like this just slipped my mind :(
So, that's the end of my post. Please consider replying with what you think of:
So, it's been a rather busy week on the mailing list. But nobody has responded here... So what's up? Is this subject not interesting? Are the questions I ask just hard to answer?
I put quite some time and effort into this, so I would appreciate a warning if this is never going to be used.
Anyway, I thought a little more about the behavioural problems I mentioned in my previous post. I explained it to a friend and in explaining the situation I figured out that an arbitrary loop may be too generic. The third problem with the two changes at the same time are a problem which only exists for arbitrary loops. If arbitrary loops are not a good idea, the packing/unpacking problems may be a different problem all together.I took another look at foldp as a loop, and the loop I would like for the game example and I noticed something which might be important. Before I show the diagrams, let me give you a proper legend first:
<elm_primitives.png>(source: "Elm: Concurrent FRP for Functional GUIs")<filter_sample_primitives.svg>(the filter/sample primitives that are in the language today)
Now the way I drew foldp as a loop in a previous thread was incorrect. Because the behaviour of foldp is that only a change in the input changes the loop/output, not a change from the loop. So using sampleOn to depict this behaviour:
<elm_fold_in-correct.svg>
As you can see, the loopback signal b cannot cause a change in the value of the signal to f(a change in the value of s changes the values of the signals to f). In the game example I would like to work, there is a similar situation:
<game_loop.svg>
--
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/groups/opt_out.
This was my previous attempt to implement the unsafe loop. I had hoped to get some comments so I could learn about Signals in the runtime. I argue that all of your examples could be implemented in pure Elm on top of this feature.https://gist.github.com/johnpmayer/5464492
On Sat, May 18, 2013 at 1:45 PM, John Mayer (gmail) <thgy...@gmail.com> wrote:
I think this is an important topic. Some thoughts:I think you're right when you say that filtered loops and sampled loops are the two main, safe use cases. It has been demonstrated that both can be implemented using a more primitive loop construct. I suggest that we make concrete the semantics of the general, unsafe loop that will inevitably be represented in the underlying runtime, and then independently discuss the merits of how much should be exposed to the programmers.Would it be possible to create a flag for the compiler that quits early and prints the entire signal graph? (even in XML or something, doesn't need to be pretty) Where is the Signal graph represented in the compiler, and how is it checked? How does the runtime actually propagate signals, and whats the difference between "resolving a signal DAG atomically" and "handling an event external to the local DAG"?
Sent from my iPhoneSo, it's been a rather busy week on the mailing list. But nobody has responded here... So what's up? Is this subject not interesting? Are the questions I ask just hard to answer?I put quite some time and effort into this, so I would appreciate a warning if this is never going to be used.
Anyway, I thought a little more about the behavioural problems I mentioned in my previous post. I explained it to a friend and in explaining the situation I figured out that an arbitrary loop may be too generic. The third problem with the two changes at the same time are a problem which only exists for arbitrary loops. If arbitrary loops are not a good idea, the packing/unpacking problems may be a different problem all together.I took another look at foldp as a loop, and the loop I would like for the game example and I noticed something which might be important. Before I show the diagrams, let me give you a proper legend first:<elm_primitives.png>(source: "Elm: Concurrent FRP for Functional GUIs")<filter_sample_primitives.svg>(the filter/sample primitives that are in the language today)Now the way I drew foldp as a loop in a previous thread was incorrect. Because the behaviour of foldp is that only a change in the input changes the loop/output, not a change from the loop. So using sampleOn to depict this behaviour:<elm_fold_in-correct.svg>As you can see, the loopback signal b cannot cause a change in the value of the signal to f(a change in the value of s changes the values of the signals to f). In the game example I would like to work, there is a similar situation:<game_loop.svg>It's a little more complicated with the different loops to different places, but the gameState signal can be seen as a foldp loopback signal and ignored for now. The playing signal is what's interesting. It connected to a filter in such a way that it's not responsib
/*
* John P Mayer, Jr
* BS, Computer and Information Science, 2011
* MSE, Embedded Systems, 2012
* School of Engineering and Applied Science
* The University of Pennsylvania
* Philadelphia, PA
*/
--
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/groups/opt_out.
I suggest that we make concrete the semantics of the general, unsafe loop that will inevitably be represented in the underlying runtime, and then independently discuss the merits of how much should be exposed to the programmers.
This was my previous attempt to implement the unsafe loop. I had hoped to get some comments so I could learn about Signals in the runtime. I argue that all of your examples could be implemented in pure Elm on top of this feature.
https://gist.github.com/johnpmayer/5464492
I think you're right when you say that filtered loops and sampled loops are the two main, safe use cases.
Jeff, I like the visualization of the signal filter primitives :)
Hmm, in thinking about implementation I thought of a potential problem. The loop would be easy to implement, but in the simplest unsafe case, it'd need to be implemented just like the async feature. The loop would go to the GED and then get sent back into an input. This allows synchronization that permits concurrency and parallelization.
That means that event could occur between the triggering event and the looped event, perhaps changing some foldp and making the looped event irrelevant or wrong. I think this would ba a problem for all proposals so far.
Printing out the signal graph would not be too hard. It could be done with some JS in Init.js that crawls over the "inputs" array and then crawls through their "kids" arrays. You could build up a list of directed edges easily.
I think we should rephrase this discussion as "signal sources and sinks". I think that's a better mental model for what we are trying to do and the loop diagrams can be quite confusing.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+unsubscribe@googlegroups.com.
<irc#elm.log>
I think it might be possible to annotate updates to make sure that they only cause N loops. This would be theoretically nicer, but I don't know if this will be nicer to use and to think about. In any case, I think we should figure that out before implementing stuff.
I think this is an important feature, but because of the roadmap I want, I cannot properly do this theoretical work right now. And I think the theory needs to be explored more fully before an approach is chosen.
We also should look at Real-Time FRP which was theoretically similar to Elm and had recursive signals.
--
You received this message because you are subscribed to a topic in the Google Groups "Elm Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elm-discuss/mDhgg1cbX4M/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to elm-discuss...@googlegroups.com.
I've tried writing this answer two times before, but couldn't find the words to easily describe the semantics of the synchronous loopback. So in stead I've made some diagrams of an example use:
0:<synchronous_loop1.svg>1:<synchronous_loop2.svg>2:<synchronous_loop3.svg>3:<synchronous_loop4.svg>4:<synchronous_loop5.svg>5:<synchronous_loop6.svg>
The scenario is consists of a few steps in which input source i1 changes to value 3, and immediately after to value 2. The images show the states between these steps:0: Before the start of the program a Change message is added to the queue of the loopback (with the loopbacks initial value). This is key to make the synchronous loop work.1: Input source i1 changes to value 3 and sends Change messages to the queues.2: The sampleOn can compute it's outgoing message because the ingoing are both there. Meanwhile input source i1 changes to value 2 and sends more change messages.3: The lifted (+) can be executed for the first time. Note that the new Change 2 message from i1 is still waiting for the result of this (+). This is the synchronous behaviour of the loop in action.4: Because the loopback had a message ready again, the sampleOn could be executed.5: The last (+) is executed. This is the last state. It looks a lot like state 0, but with a different message ready at the loopback and some messages available at the output signal (the one pointing downwards).Does that make the semantics of the synchronous loopback clear?The asynchronous loopback is definitely something very different from anything you might do with foldp, because that kind of a loop might happily work with incoming messages and an old version of the state. And when the new state finally arrives through the asynchronous loopback, it might get ignored. Example like the last one:
0:<asynchronous_loop1.svg>1:<asynchronous_loop2.svg>2:<asynchronous_loop3.svg>3:<asynchronous_loop4.svg>4:<asynchronous_loop5.svg>5:<asynchronous_loop6.svg>6:<asynchronous_loop7.svg>7:<asynchronous_loop8.svg>8:<asynchronous_loop9.svg>