[Ur] New attempt to wrap a simple JS datepicker library (Pikaday) to use with Ur/Web

Stefan Scott Alexander stefanscottalexx at gmail.com
Fri Aug 7 09:20:13 EDT 2015


Thank you Ziv for these 2 very helpful suggestions - they seem to be
heading in the right direction.

I have incorporated them, and now I'm getting different (but possibly
"better"?) compiler errors.


Suggestion (1)

You provided a reminder of your earlier suggestion to use this pattern:

  <textbox{#Field} id={nid}/>
  <active code={init nid; return <xml/>}/>

This does seem like a vast improvement over my previous code (which had an
`onload` event in the <body> tag, which I had simply copied from David
Patterson's "Democracy Now" example) - since, as you pointed out, the
`onload` event was probably problematic, because the node in question
probably didn't exist yet.

I have now changed the code as follows:

  https://github.com/StefanScott/urweb-pikaday/blob/master/pikadayPage.ur

OLD:

  <form onload={init foo_id}>
    <textbox{#DateField} id={foo_id}/>
    <submit action={handler}/>
  </form>

NEW:

  <form>
    <textbox{#DateField} id={foo_id}/>
    <active code={init foo_id; return <xml/>}/>
    <submit action={handler}/>
  </form>

This now gave the following compile errors:

$ urweb pikadayPage

pikadayPage.ur:27:3: (to 29:12) Error in final record unification
Can't unify record constructors
Have:  [Dyn = (), MakeForm = (), Body = ()]
Need:  [Form = (), Dyn = (), Body = ()]

pikadayPage.ur:27:3: (to 29:12) Stuck unifying these records after
canceling matching pieces:
Have:  [MakeForm = ()]
Need:  [Form = ()]

pikadayPage.ur:28:3: (to 29:12) Error in final record unification
Can't unify record constructors
Have:  <UNIF:U526::{Unit}> ++ [Form = ()]
Need:  [Dyn = (), MakeForm = (), Body = ()]

pikadayPage.ur:28:3: (to 29:12) Stuck unifying these records after
canceling matching pieces:
Have:  ([Form = ()]) ++ <UNIF:U526::{Unit}>
Need:  [Dyn = (), MakeForm = (), Body = ()]

$

Well... It looks like the compiler is *almost* happy - if the only conflict
now remaining is between a MakeForm field and a Form field.

However, I do not know what these two fields mean, or where they come from,
so I don't know how to attempt to resolve this compile error.


Suggestion (2):

I haven't yet tried creating a wrapper function (like `activate` in
Logitext) in accordance with your second suggestion - but after (ie, in
addition to) doing suggestion (1) above, I did also try making a quick
change to the result type in pikadayControl.urs - changing it from
`transaction unit` to `transaction xbody`:


https://github.com/StefanScott/urweb-pikaday/blob/master/pikadayControl.urs

OLD:

val init :
  id ->
  transaction unit

NEW:

val init :
  id ->
  transaction xbody

I was expecting that this might actually compile, since it seemed that the
new "result type" `transaction xbody` might be more appropriate for use in
the <active> tag added in Suggestion (1):

  <active code={init foo_id; return <xml/>}/>

However, this gave a different (but possibly also helpful?) compile error:

$ urweb pikadayPage

pikadayPage.ur:27:24: (to 27:54) Unification failure

Expression:
fn _ : {} =>
 return [<UNIF:U458::Type -> Type>]
  [xml <UNIF:U460::{Unit}> <UNIF:U461::{Type}> ([])] _
  (Basis.cdata [<UNIF:U460::{Unit}>] [<UNIF:U461::{Type}>] "")

Have con:
{} ->
 <UNIF:U458::Type -> Type>
  (xml <UNIF:U460::{Unit}> <UNIF:U461::{Type}> ([]))

Need con:
(xml ([Dyn = (), MakeForm = (), Body = ()]) ([]) ([])) ->
 transaction <UNIF:U453::Type>

Incompatible constructors
Have:  {}
Need:  xml ([Dyn = (), MakeForm = (), Body = ()]) ([]) ([])

$

This error message seems somewhat similar to the previous error message. It
seems to be saying that there is some incompatibility among the following
pieces:

(a) the "result type" of function `init` as declared in file
pikadayControl.urs

(b) the "result type" of the curly-bracketed expression in the tag:

  <active code={init foo_id; return <xml/>}/>

(c) possibly also the "result type" being returned by the JavaScript `init`
function as defined in pikadayControl.js


The JavaScript `init` function:

By the way, here is the JavaScript function `init`:

https://github.com/StefanScott/urweb-pikaday/blob/master/pikadayControl.js

function init ( nodeId ) = {
  var picker = new Pikaday ( {
    field: document.getElementById(nodeId),
    firstDay: 1,
    minDate: new Date('2000-01-01'),
    maxDate: new Date('2020-12-31'),
    yearRange: [2000,2020]
  } ) ;
}

It is a slight modification of the JavaScript provided in the Pikaday demo:

  http://dbushell.github.io/Pikaday/

Thiss JavaScript function appears to take an argument `nodeId`, and creates
a `new Pikaday` attached to that node, assigning the result to a variable
called `picker`

I don't *think* this JavaScript `init` function actually returns anything:
apparently the `var picker` is merely a "throwaway" (?) and the function is
being run simply for its side-effect (attaching the `new Pikaday` to the
node `nodeId`)?

This makes me wonder if the "result type" of this `init` function (in
JavaScript) might also dictate the "result type" of its corresponding
Ur/Web FFI declaration (which was previously `transaction unit` and is now
`transaction xbody`).


Remarks:

The compile error messages are providing intriguing clues about these
interdependencies between the various pieces.

However, I don't yet have enough experience in this area to be able to have
a truly "deterministic" methodology for writing this stuff - I'm simply
using trial and error, throwing various syntaxes at the compiler and trying
to decipher the error messages.

Thanks for any further help!

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


More information about the Ur mailing list