[Ur] Live demo and tutorial for a simple autocomplete widget written using RxJS + Mithril + 6to5/Babel + HTML5 <datalist>. Could this provide a basis for a simple "native" autocomplete widget in Ur/Web?

Stefan Scott Alexander stefanscottalexx at gmail.com
Mon Jul 13 02:52:36 EDT 2015


TL;DR: A data-bound autocomplete widget will finally make it really
practical to use Ur/Web as stated on its website:

"Ur/Web supports construction of dynamic web applications backed by SQL
databases."

It would be great if someone good at front-end programming using Ur/Web FRP
could contribute this kind of autocomplete widget.

And the example of the existing Mithril+RxJS autocomplete widget might be
able to provide some help.

===

(I) Live demo:

Here is a live demo of an autocomplete widget written using RxJS + Mithril
+ 6to5 aka Babel + HTML5 <datalist> [1]:

http://codepen.io/ericponto/pen/mJEyPL

The code can be downloaded by clicking on "Share" and then clicking on
"Export .zip" - and then it can be run in any browser, with no need for a
server.

It's tiny - just three files:

- index.html

- ../babel/index.babel - (written in babel aka 6to5) which compiles to =>

- ../js/index.js.


(II) Tutorial:

There is also a nice, "literate-programming-style" tutorial for the live
demo:

http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/

So here we have a short, simple implementation of a basic autocomplete
widget written in the minimal, functional, FRP-friendly JavaScript
framework Mithril.

Specifically, this autocomplete widget is using:

(1) Mithril: the tiny-footprint (12k gzipped), high-performance,
FRP-friendly React-like JavaScript framework

http://lhorie.github.io/mithril/

(2) RxJS: reactive extensions for JavaScript

https://github.com/Reactive-Extensions/RxJS

(3) 6to5 or Babel: the compiler providing a layer of "functional" syntactic
sugar of JavaScript and allowing programmers to use the new, functional
ECMAscript 6 before its release

https://babeljs.io/

(Warning: The babel homepage sometimes doesn't open in Chrome.)


(III) Questions:

(1) Could this simple RxJS+Mithril+Babel autocomplete widget example
provide a short path towards implementing a simple autocomplete widget
"natively" in Ur/Web (using FRP)?

(2) Could Mithril be a good "fit" with Ur/Web somehow?

(3) If so, what would be the best way to leverage Mithril in Ur/Web?

(a) "wrap" Mithril using Ur/Web's JavaScript FFI?

(b) use Mithril's implementation as a reference and emulate / re-implement
some or all of it from scratch using Ur/Web FRP?

(c) or maybe Ur/Web's FRP already does what Mithril does, but better, so
Mithril has *nothing* to offer Ur/Web?


(IV) Conjectures:

Even if (3)(c) above is true, it seems that this might provide additional
support for the question asked in the subject of this message, ie:

Can the autocomplete widget implemented in RxJS + Mithril + 6to5 serve as
an inspiration or template for implementing a similar widget natively using
Ur/Web's FRP?

Intuitively, it seems that the "shape" of this RxJS + Mithril + 6to5
implementation of an autocomplete widget might somehow be "similar" to the
"shape" of some code which would implement the same widget in Ur/Web.


(V) Possibly related recent work in functional and functional-reactive
JavaScript libraries:

There has been a flurry of activity over the past couple years involving
functional programming and functional-reactive programming with JavaScript
libraries.

A short opinionated list (from a programmer who likes functional, strongly
typed languages) can be seen here.

http://doshitan.com/js-overview-early-2015/#mithril
(Ignore item 1 talking about Angular! - I think that's just what he has to
use at his job!)

It is also fascinating the read the ReadMe (really a bit of a manifesto) of
the Re-Frame project on GitHub (which uses React, a ClojureScript "wrapper"
over Facebook React):

https://github.com/Day8/re-frame

I would imagine it can be interesting for Ur/Web programmers to be aware of
these functional and functional-reactive tendencies in JavaScript
libraries, because:

(1) They may be somewhat related to Ur/Web FRP front-end programming, eg,
they may suggest useful algorithms or techniques; or

(2) It may be worth "wrapping" some of these functional and
functional-reactive JavaScript libraries by:

(a) "wrapping" them via Ur/Web's FFI; or

(b) "emulating" them by writing portions of either:

(i) their implementations; or

(ii) implementations of *examples written in them*

... "natively" from scratch using Ur/Web's FRP.


(VI) MithrilJS:

Mithril is an interesting JavaScript library because it's tiny and
functional-reactive and fast.

https://lhorie.github.io/mithril/benchmarks.html

It's also compact and expressive:

http://lhorie.github.io/mithril-blog/a-spreadsheet-in-60-lines-of-javascript.html

Its implementation is short enough that you can actually read and
understand the whole thing in a day:

https://github.com/lhorie/mithril

Perhaps the most convincing stuff to read on Mithril is posts on
news.ycombinator.com from other programmers:

https://news.ycombinator.com/item?id=8973867

https://www.google.com/?gws_rd=ssl#q=site:news.ycombinator.com+mithril

Finally, the tutorial for the autocomplete live demo using RxJS + Mithril +
6to5 even explains what to do "when pairing Mithril with a FRP library":

http://www.ericponto.com/blog/2015/05/31/rxjs-and-mithril/

So this suggests that Mithril may in some way be a good "fit" to use with
Ur/Web.


(VI) Mithril: Can it contribute to Ur/Web?

I am curious about how Mithril might be able to fit with or contribute to
Ur/Web.

Specifically I wonder if the Mitril + RxJS implementation of an
autocomplete widget can help towards implementing a similar widget natively
in Ur/Web using FRP.

Of course, I'm *not* saying that Mithril should somehow *replace* Ur/Web's
native front-end facilities.

But I *am* wondering if there could be some sort of cross-pollination here,
in some form.

For example, given ...

- the current lack of examples and demos of Ur/Web FRP programming*

- Mithril's functional approach, and FRP-friendliness

... I wonder if Mithril could serve as some kind of inspiration, in
particular for a back-end database programmer trying to learn how to do FRP
in Ur/Web.

---

* By the way, I would like to mention that the chat examples in this PDF
are amazing:

http://adam.chlipala.net/papers/UrWebPOPL15/UrWebPOPL15.pdf

This is some of the most inspiring web programming code I've ever seen.
Amazingly compact and expressive and helpful.

If there were examples of nice Ur/Web FRP idioms available, it would be
immensely helpful for programmers learning Ur/Web.


(VIII) Why a (native or FFI) autocomplete widget (in particular) could be
very important for Ur/Web:

Having a community-contributed autocomplete widget for Ur/Web, implemented
either:

- "natively" using Ur/Web FRP, or

- as an FFI "wrapper" around an existing full-featured library such as
Select2 or twitter typeahead.js

... would finally make it really practical for Ur/Web to be used by more
application developers as a web database framework (particular those who
are good at back-end programming and not-so-good at front-end programming).

This is because an autocomplete widget is essential for providing a
friendly UI where users editing a "child" record can use a convenient menu
to select the value of a foreign-key field to link it to the appropriate
"parent" record - rather than having to manually find, memorize and enter
the parent record's autoincrement/surrogate integer primary key.

Developers who are good at data-modeling and SQL on the back-end (but might
not be so good at functional-reactive programming on the front end) would
benefit greatly if some Ur/Web programmer(s) who are good at front-end
programming could provide a "native" implementation of an autocomplete
 using Ur/Web's FRP - perhaps inspired by the Mithril+RxJS+Babel
autocomplete example described in this post.

===

Source code or the RxJS + Mithril + 6to5 + Html5 DataList autocomplete
widget example:

Below are just for the 2 human-written files index.html and index.babel.

File index.babel is quite similar to third file (not shown): index.js -
which is output by the compiler. However, index.babel uses a more
"functional" syntax.

I hope that if the brief code below implementing an autocomplete widget is
read by some some Ur/Web programmers (who are also good at front-end
development) you will think: "This looks a lot like something I could
implement 'natively' in Ur/Web".

It would probably only take a page of code (for an Ur/Web programmer who is
good at front-end development) to implement a simple data-bound
autocomplete widget using Ur/Web's FRP.

===

###  this file:
###  index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>RxJS and Mithril Autocomplete Example</title>
  </head>
  <body>

    <div id="autocomplete"></div>

    <script src='
https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.2/rx.all.min.js'></script>
    <script src='
https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.0/mithril.min.js
'></script>

    <script src="js/index.js"></script>

  </body>
</html>

===

###  this file:
### ../babel/index.babel

###  compiles to:
###  ../js/index.js

var pluck = Rx.helpers.pluck;

var searchGithub = function(term) {
return m.request({
    method: "GET",
    url: `https://api.github.com/search/repositories?q=${term}`
  });
};

var el = document.querySelector("#autocomplete");

var AutoComplete = {
  controller() {
    this.data = m.prop({});

    Rx.Observable.fromEvent(el, "keyup")
     .map(pluck("target")) /* get element */
     .filter(el => el.matches("input")) /* make sure it is the input */
     .map(pluck("value")) /* get element's value */
     .filter(val => val.length > 2) /* at least 3 chars */
     .debounce(250) /* debounce it */
     .distinctUntilChanged() /* ignore non character keyups */
     .flatMapLatest(searchGithub) /* fire request */
     .subscribe(this.data); /* set data prop with results */
  },
  view(ctrl) {
    var data = ctrl.data();

    return m(".autocomplete", [
      m("label[for=search]", ["Search for Github repo: "]),
      m("input#search[list=results]"),
      m("datalist#results", [
        data.items && data.items.map(item => m("option[value=" + item.name
+ "]"))
      ])
    ]);
}
};

m.mount(el, AutoComplete);

===

Again, the complete source for the above demo can be downloaded from the
link below, and can be run locally without a webserver (ie by simply
opening the index.html file directly in a browser):

http://codepen.io/ericponto/pen/mJEyPL

The source can be downloaded by clicking on "Share" > "Export .zip"

===

[1] Caveat: This RxJS + Mithril + 6to5 aka Babel + HTML5 DataList
autocomplete relies on the HTML5 DataList element - which has a couple of
limitations:

- only usable in newer browsers

- also some limitation about the DOM, can't do but I can't remember (?) -

These limitations suggest that it may also be necessary to provide
additional implementations of an autocomplete widget in Ur/Web which do not
rely on on HTML5 <datalist>.

###
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.impredicative.com/pipermail/ur/attachments/20150713/b5fc7781/attachment-0001.html>


More information about the Ur mailing list