<div dir="ltr"><div>[This message is almost identical to the previous message; but it fixes a few typos.]</div><div><br></div><div>TL;DR: A data-bound autocomplete widget will finally make it really</div><div>practical to use Ur/Web as stated on its website:</div><div><br></div><div>"Ur/Web supports construction of dynamic web applications backed by SQL</div><div>databases."</div><div><br></div><div>It would be great if someone good at front-end programming using Ur/Web FRP</div><div>could contribute this kind of autocomplete widget.</div><div><br></div><div>And the example of the existing Mithril+RxJS autocomplete widget might be</div><div>able to provide some help.</div><div><br></div><div>===</div><div><br></div><div>(I) Live demo:</div><div><br></div><div>Here is a live demo of an autocomplete widget written using RxJS + Mithril</div><div>+ 6to5 aka Babel + HTML5 <datalist> [1]:</div><div><br></div><div><a href="http://codepen.io/ericponto/pen/mJEyPL">http://codepen.io/ericponto/pen/mJEyPL</a></div><div><br></div><div>The code can be downloaded by clicking on "Share" and then clicking on</div><div>"Export .zip" - and then it can be run in any browser, with no need for a</div><div>server.</div><div><br></div><div>It's tiny - just three files:</div><div><br></div><div>- index.html</div><div><br></div><div>- ../babel/index.babel - (written in babel aka 6to5) which compiles to =></div><div><br></div><div>- ../js/index.js.</div><div><br></div><div><br></div><div>(II) Tutorial:</div><div><br></div><div>There is also a nice, "literate-programming-style" tutorial for the live</div><div>demo:</div><div><br></div><div><a href="http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/">http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/</a></div><div><br></div><div>So here we have a short, simple implementation of a basic autocomplete</div><div>widget written in the minimal, functional, FRP-friendly JavaScript</div><div>framework Mithril.</div><div><br></div><div>Specifically, this autocomplete widget is using:</div><div><br></div><div>(1) Mithril: the tiny-footprint (12k gzipped), high-performance,</div><div>FRP-friendly React-like JavaScript framework</div><div><br></div><div><a href="http://lhorie.github.io/mithril/">http://lhorie.github.io/mithril/</a></div><div><br></div><div>(2) RxJS: reactive extensions for JavaScript</div><div><br></div><div><a href="https://github.com/Reactive-Extensions/RxJS">https://github.com/Reactive-Extensions/RxJS</a></div><div><br></div><div>(3) 6to5 or Babel: the compiler providing a layer of "functional" syntactic</div><div>sugar of JavaScript and allowing programmers to use the new, functional</div><div>ECMAscript 6 before its release</div><div><br></div><div><a href="https://babeljs.io/">https://babeljs.io/</a></div><div><br></div><div>(Warning: The babel homepage sometimes doesn't open in Chrome.)</div><div><br></div><div><br></div><div>(III) Questions:</div><div><br></div><div>(1) Could this simple RxJS+Mithril+Babel autocomplete widget example</div><div>provide a short path towards implementing a simple autocomplete widget</div><div>"natively" in Ur/Web (using FRP)?</div><div><br></div><div>(2) Could Mithril be a good "fit" with Ur/Web somehow?</div><div><br></div><div>(3) If so, what would be the best way to leverage Mithril in Ur/Web?</div><div><br></div><div>(a) "wrap" Mithril using Ur/Web's JavaScript FFI?</div><div><br></div><div>(b) use Mithril's implementation as a reference and emulate / re-implement</div><div>some or all of it from scratch using Ur/Web FRP?</div><div><br></div><div>(c) or maybe Ur/Web's FRP already does what Mithril does, but better, so</div><div>Mithril has *nothing* to offer Ur/Web?</div><div><br></div><div><br></div><div>(IV) Conjectures:</div><div><br></div><div>Even if (3)(c) above is true, it seems that this might provide additional</div><div>support for the question asked in the subject of this message, ie:</div><div><br></div><div>Can the autocomplete widget implemented in RxJS + Mithril + 6to5 serve as</div><div>an inspiration or template for implementing a similar widget natively using</div><div>Ur/Web's FRP?</div><div><br></div><div>Intuitively, it seems that the "shape" of this RxJS + Mithril + 6to5</div><div>implementation of an autocomplete widget might somehow be "similar" to the</div><div>"shape" of some code which would implement the same widget in Ur/Web.</div><div><br></div><div><br></div><div>(V) Possibly related recent work in functional and functional-reactive</div><div>JavaScript libraries:</div><div><br></div><div>There has been a flurry of activity over the past couple years involving</div><div>functional programming and functional-reactive programming with JavaScript</div><div>libraries.</div><div><br></div><div>A short opinionated list (from a programmer who likes functional, strongly</div><div>typed languages) can be seen here.</div><div><br></div><div><a href="http://doshitan.com/js-overview-early-2015/#mithril">http://doshitan.com/js-overview-early-2015/#mithril</a></div><div>(Ignore item 1 talking about Angular! - I think that's just what he has to</div><div>use at his job!)</div><div><br></div><div>It is also fascinating the read the ReadMe (really a bit of a manifesto) of</div><div>the Re-Frame project on GitHub (which uses React, a ClojureScript "wrapper"</div><div>over Facebook React):</div><div><br></div><div><a href="https://github.com/Day8/re-frame">https://github.com/Day8/re-frame</a></div><div><br></div><div>I would imagine it can be interesting for Ur/Web programmers to be aware of</div><div>these functional and functional-reactive tendencies in JavaScript</div><div>libraries, because:</div><div><br></div><div>(1) They may be somewhat related to Ur/Web FRP front-end programming, eg,</div><div>they may suggest useful algorithms or techniques; or</div><div><br></div><div>(2) It may be worth leveraging some of these functional and</div><div>functional-reactive JavaScript libraries by:</div><div><br></div><div>(a) "wrapping" them via Ur/Web's FFI; or</div><div><br></div><div>(b) "emulating" them by writing portions of either:</div><div><br></div><div>(i) their implementations; or</div><div><br></div><div>(ii) implementations of *examples written in them*</div><div><br></div><div>... "natively" from scratch using Ur/Web's FRP.</div><div><br></div><div><br></div><div>(VI) MithrilJS:</div><div><br></div><div>Mithril is an interesting JavaScript library because it's tiny and</div><div>functional-reactive and fast.</div><div><br></div><div><a href="https://lhorie.github.io/mithril/benchmarks.html">https://lhorie.github.io/mithril/benchmarks.html</a></div><div><br></div><div>It's also compact and expressive:</div><div><br></div><div><a href="http://lhorie.github.io/mithril-blog/a-spreadsheet-in-60-lines-of-javascript.html">http://lhorie.github.io/mithril-blog/a-spreadsheet-in-60-lines-of-javascript.html</a></div><div><br></div><div>Its implementation is short enough that you can actually read and</div><div>understand the whole thing in a day:</div><div><br></div><div><a href="https://github.com/lhorie/mithril">https://github.com/lhorie/mithril</a></div><div><br></div><div>Perhaps the most convincing stuff to read on Mithril is posts on</div><div><a href="http://news.ycombinator.com">news.ycombinator.com</a> from other programmers:</div><div><br></div><div><a href="https://news.ycombinator.com/item?id=8973867">https://news.ycombinator.com/item?id=8973867</a></div><div><br></div><div><a href="https://www.google.com/?gws_rd=ssl#q=site:news.ycombinator.com+mithril">https://www.google.com/?gws_rd=ssl#q=site:news.ycombinator.com+mithril</a></div><div><br></div><div>Finally, the tutorial for the autocomplete live demo using RxJS + Mithril +</div><div>6to5 even explains what to do "when pairing Mithril with a FRP library":</div><div><br></div><div><a href="http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/">http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/</a></div><div><br></div><div>So this suggests that Mithril may in some way be a good "fit" to use with</div><div>Ur/Web.</div><div><br></div><div><br></div><div>(VI) Mithril: Can it contribute to Ur/Web?</div><div><br></div><div>I am curious about how Mithril might be able to fit with or contribute to</div><div>Ur/Web.</div><div><br></div><div>Specifically I wonder if the Mitril + RxJS implementation of an</div><div>autocomplete widget can help towards implementing a similar widget natively</div><div>in Ur/Web using FRP.</div><div><br></div><div>Of course, I'm *not* saying that Mithril should somehow *replace* Ur/Web's</div><div>native front-end facilities.</div><div><br></div><div>But I *am* wondering if there could be some sort of cross-pollination here,</div><div>in some form.</div><div><br></div><div>For example, given ...</div><div><br></div><div>- the current lack of examples and demos of Ur/Web FRP programming*</div><div><br></div><div>- Mithril's functional approach, and FRP-friendliness</div><div><br></div><div>... I wonder if Mithril could serve as some kind of inspiration, in</div><div>particular for a back-end database programmer trying to learn how to do FRP</div><div>in Ur/Web.</div><div><br></div><div>---</div><div><br></div><div>* By the way, I would like to mention that the chat examples in this PDF</div><div>are amazing:</div><div><br></div><div><a href="http://adam.chlipala.net/papers/UrWebPOPL15/UrWebPOPL15.pdf">http://adam.chlipala.net/papers/UrWebPOPL15/UrWebPOPL15.pdf</a></div><div><br></div><div>This is some of the most inspiring web programming code I've ever seen.</div><div>Amazingly compact and expressive and helpful.</div><div><br></div><div>If there were more examples of such nice Ur/Web FRP idioms available, it would be</div><div>immensely helpful for programmers learning Ur/Web.</div><div><br></div><div><br></div><div>(VIII) Why a (native or FFI) autocomplete widget (in particular) could be</div><div>very important for Ur/Web:</div><div><br></div><div>Having a community-contributed autocomplete widget for Ur/Web, implemented</div><div>either:</div><div><br></div><div>- "natively" using Ur/Web FRP, or</div><div><br></div><div>- as an FFI "wrapper" around an existing full-featured library such as</div><div>Select2 or twitter typeahead.js</div><div><br></div><div>... would finally make it really practical for Ur/Web to be used by more</div><div>application developers as a web database framework (particular those who</div><div>are good at back-end programming and not-so-good at front-end programming).</div><div><br></div><div>This is because an autocomplete widget is essential for providing a</div><div>friendly UI where users editing a "child" record can use a convenient menu</div><div>to select the value of a foreign-key field to link it to the appropriate</div><div>"parent" record - rather than having to manually find, memorize and enter</div><div>the parent record's autoincrement/surrogate integer primary key.</div><div><br></div><div>Developers who are good at data-modeling and SQL on the back-end (but might</div><div>not be so good at functional-reactive programming on the front end) would</div><div>benefit greatly if some Ur/Web programmer(s) who are good at front-end</div><div>programming could provide a "native" implementation of an autocomplete</div><div> using Ur/Web's FRP - perhaps inspired by the Mithril+RxJS+Babel</div><div>autocomplete example described in this post.</div><div><br></div><div>===</div><div><br></div><div>Source code or the RxJS + Mithril + 6to5 + Html5 DataList autocomplete</div><div>widget example:</div><div><br></div><div>Below are just the 2 human-written files index.html and index.babel.</div><div><br></div><div>File index.babel is quite similar to third file (not shown): index.js -</div><div>which is output by the compiler. However, index.babel uses a more</div><div>"functional" syntax.</div><div><br></div><div>I hope that if the brief code below implementing an autocomplete widget is</div><div>read by some Ur/Web programmers (who are also good at front-end</div><div>development) some might will think: "This looks a lot like something I could</div><div>implement 'natively' in Ur/Web".</div><div><br></div><div>It would probably only take a page of code (for an Ur/Web programmer who is</div><div>good at front-end development) to implement a simple data-bound</div><div>autocomplete widget using Ur/Web's FRP.</div><div><br></div><div>===</div><div><br></div><div>###  this file:</div><div>###  index.html</div><div><br></div><div><!DOCTYPE html></div><div><html></div><div>  <head></div><div>    <meta charset="UTF-8"></div><div>    <title>RxJS and Mithril Autocomplete Example</title></div><div>  </head></div><div>  <body></div><div><br></div><div>    <div id="autocomplete"></div></div><div><br></div><div>    <script src='</div><div><a href="https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.2/rx.all.min.js">https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.2/rx.all.min.js</a>'></script></div><div>    <script src='</div><div><a href="https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.0/mithril.min.js">https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.0/mithril.min.js</a></div><div>'></script></div><div><br></div><div>    <script src="js/index.js"></script></div><div><br></div><div>  </body></div><div></html></div><div><br></div><div>===</div><div><br></div><div>###  this file:</div><div>### ../babel/index.babel</div><div><br></div><div>###  compiles to:</div><div>###  ../js/index.js</div><div><br></div><div>var pluck = Rx.helpers.pluck;</div><div><br></div><div>var searchGithub = function(term) {</div><div>return m.request({</div><div>    method: "GET",</div><div>    url: `<a href="https://api.github.com/search/repositories?q=${term}`">https://api.github.com/search/repositories?q=${term}`</a></div><div>  });</div><div>};</div><div><br></div><div>var el = document.querySelector("#autocomplete");</div><div><br></div><div>var AutoComplete = {</div><div>  controller() {</div><div>    this.data = m.prop({});</div><div><br></div><div>    Rx.Observable.fromEvent(el, "keyup")</div><div>     .map(pluck("target")) /* get element */</div><div>     .filter(el => el.matches("input")) /* make sure it is the input */</div><div>     .map(pluck("value")) /* get element's value */</div><div>     .filter(val => val.length > 2) /* at least 3 chars */</div><div>     .debounce(250) /* debounce it */</div><div>     .distinctUntilChanged() /* ignore non character keyups */</div><div>     .flatMapLatest(searchGithub) /* fire request */</div><div>     .subscribe(this.data); /* set data prop with results */</div><div>  },</div><div>  view(ctrl) {</div><div>    var data = ctrl.data();</div><div><br></div><div>    return m(".autocomplete", [</div><div>      m("label[for=search]", ["Search for Github repo: "]),</div><div>      m("input#search[list=results]"),</div><div>      m("datalist#results", [</div><div>        data.items && data.items.map(item => m("option[value=" + <a href="http://item.name">item.name</a></div><div>+ "]"))</div><div>      ])</div><div>    ]);</div><div>}</div><div>};</div><div><br></div><div>m.mount(el, AutoComplete);</div><div><br></div><div>===</div><div><br></div><div>Again, the complete source for the above demo can be downloaded from the</div><div>link below, and can be run locally without a webserver (ie by simply</div><div>opening the index.html file directly in a browser):</div><div><br></div><div><a href="http://codepen.io/ericponto/pen/mJEyPL">http://codepen.io/ericponto/pen/mJEyPL</a></div><div><br></div><div>The source can be downloaded by clicking on "Share" > "Export .zip"</div><div><br></div><div>===</div><div><br></div><div>[1] Caveat: This RxJS + Mithril + 6to5 aka Babel + HTML5 DataList</div><div>autocomplete relies on the HTML5 DataList element - which has a couple of</div><div>limitations:</div><div><br></div><div>- only usable in newer browsers</div><div><br></div><div>- also some limitation about the DOM which I can't remember (?) -</div><div><br></div><div>These limitations suggest that it may also be necessary to provide</div><div>additional implementations of an autocomplete widget in Ur/Web which do *not*</div><div>rely on on HTML5 <datalist>.</div><div><br></div><div>###</div></div>