<br><div class="gmail_quote">On Sat, Feb 25, 2012 at 12:57 PM, Adam Chlipala <span dir="ltr"><<a href="mailto:adamc@impredicative.com">adamc@impredicative.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Meta-answer to your question: Ur/Web is not like the typical programming language. It embodies one particular vision (mine) for how web apps should be programmed, via features built into the compiler and runtime system. It is not easy to go beyond this model (could be impossible without modifying the core language implementation), but you might find that the model already supports what you want.</blockquote>
<div><br></div><div>I've been studying Ur and Ur/Web further since my comment a few days past. I think I could go ahead with it - the framework would be no more awkward in Ur than in Haskell, at least. But the integration would probably compromise some of Ur's features, especially your use of `known(Foo)` due to indirection through a shared signal/triggering framework for the reactive updates. </div>
<div><br></div><div>No matter what web framework I use, I'll be facing some awkwardness.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
David Barbour wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'm very interested in Ur as a platform for a new (from 2010) impure declarative programming model called `Reactive Demand Programming` (RDP).<br>
</blockquote>
<br></div>
Perhaps you could describe a simple RDP example that would be illustrative to implement in Ur/Web? Much of your discussion is too abstract for me ATM.</blockquote><div><br></div><div>Most simple examples fail to distinguish RDP from other reactive paradigms, unfortunately. RDP will only shine if we scale to mashups, where problems include consistent data fusion from independent services, synchronous commands on independent services, mutable views of mutable views, and all the associated problems of resilient and disruption-tolerant subscription management. </div>
<div><br></div><div>But one simple problem might be shared text editing, where we have multiple users observing a form and some of them editing it concurrently. RDP would maintain consistent views of the form and have state models that resolve simultaneous edits deterministically (but arbitrarily).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br></div>
The _only_ GUI model built into Ur/Web is one that I call reactive. Perhaps it would be helpful for you to go through the main demo:<br>
<a href="http://www.impredicative.com/ur/demo/" target="_blank">http://www.impredicative.com/<u></u>ur/demo/</a><br>
Reactive GUI features are used in all of the demo programs starting with "React."</blockquote><div><br></div><div>Yeah, that's a reactive GUI. It's useful, but sort of isolated. RDP would be much more about reactivity at the server, and maintaining consistent views across multiple clients (and multiple servers, in case of mashups). </div>
<div><br></div><div>If I do go through with RDP in Ur (I've tentatively named the project URDP), I will probably leverage the reactive GUI to centralize the relationship between client state and server state. It would simplify the implementation, I think, and also integration with other Ur/Web systems. This was, at least, one of the positives I listed when studying Ur.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br></div><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
RDP doesn't require general dependent types, but it would be very useful to represent `logical latency` in composition of certain types, or at least to constrain by it. Would this be feasible with the metaprogramming facilities?<br>
</blockquote>
<br></div>
Possibly. I can give a better answer if you incorporate this in an example like I suggested above.</blockquote><div><br></div><div>I've since determined that I cannot do so. RDP uses continuous time, but Ur's metaprogramming only supports discrete computation. This isn't a problem, though; a dynamic approach isn't ideal, but works just fine.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Would it be difficult to upgrade an Ur/Web application at runtime? I.e. support for staging, runtime compilation, specialization? I'd like the server itself to be reactive, ultimately, and to support a lot of live programming.<br>
</blockquote>
<br></div>
The only way to do live update now is to interpose a proxy that holds client connections while the old server process is exiting and a new one is starting. Perhaps the functionality you want can be achieved in part by implementing an interpreter for a small language inside of Ur/Web.</blockquote>
<div><br></div><div>Well, I can always do an interpreter, of course. But without something like tracing JIT, it will never be anywhere near the performance of the native code. And I'd also lose a lot of Ur's safety properties. </div>
<div><br></div><div>Oh well. I didn't really expect this feature. I'm no worse off in this regard than I would be in Haskell or ML.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im"><br></div>
It's easy to start a server process with an arbitrary number of OS threads to handle client connections, and they all run in parallel. There is also support for periodic tasks, which run in their own threads, alternating between sleeping N seconds and running single transactions.</blockquote>
<div><br></div><div>That would probably be sufficient for my purposes, if not ideal. But I think it wouldn't take much extra effort to add some way for client code to signal the periodic tasks, to avoid polling, if I did take that route. Via channel, perhaps. </div>
<div> </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">What about client-side parallelism?<br>
</blockquote>
<br>
Ur/Web supports cooperative multi-threading in client-side code, which I call concurrency, but not parallelism, which can't be achieved in standard browser JavaScript, with its inherent serialization of code execution.</blockquote>
<div><br></div><div>Someday we'll have WebCL. ;)</div><div><br></div><div>But I was just curious. I don't see much immediate need for web workers or client-side parallelism. </div><div><br></div><div><a href="http://www.khronos.org/webcl/">http://www.khronos.org/webcl/</a></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
RDP requires some non-traditional shared state models, especially to resolve concurrent interaction with state. Ur/Web focuses on SQL with its arbitrary serialization of updates, but would there be anything preventing alternative state models?<br>
</blockquote>
<br></div>
No. You can use the C FFI to implement something new and make it play nicely with transactions. If you can't make it transactional, then to a first approximation it can't be made to work. </blockquote><div><br>
</div><div>RDP is designed for optimistic concurrency closer in nature to a time warp protocol, complete with retroactive corrections up to some limited window. It would be easy enough to express the same mechanisms with transactional state, though it would be an unfortunate source of inefficiency with a negligible contribution to consistency.</div>
<div><br></div><div>Ur puts the entire webpage into a transaction monad at the toplevel, which handles your use cases well. I guess efficiency will be a tradeoff I need to make here if I pursue Ur with RDP.</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br></div><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I saw mention of AJAX and COMET, but I haven't looked much into it yet. Would it be difficult to write a web-app that uses WebSockets for server push, when they are available, and falls back to the more hackish mechanisms otherwise?<br>
</blockquote>
<br></div>
You might be able to do various things with the C FFI, and it should also be possible to add a compiler option to implement RPCs and message-passing via alternate backend technologies (without requiring changes to application source).</blockquote>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
How efficient is the generated JavaScript code?<br>
</blockquote>
<br></div>
It's not at all tuned for maximum performance, but it's generally worked out well for me so far, on recent machines/browsers.<br></blockquote><div><br></div><div><div>It might be worth researching a few hand-tuned open JavaScript libraries to get performance and efficiency benefits, both for the reactive GUI code (e.g. Backbone) and the sockets aspects (e.g. Socket.IO). At least, if you're interested in supporting high-performance web-apps. Generating high performance client code is just as important as your server-side code, IMO.</div>
<div><br></div><div><br></div></div></div>