Re: An IDL for SCXML interpreters
David Junger <[email protected]> Wed, 15 Jul 2015 09:00:25 +0200
| Newsgroups | gmane.comp.web.voice |
|---|---|
| Message-ID | <[email protected]> |
--Apple-Mail=_667083EC-150B-4DAA-A55A-FF964E63F47A Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Sorry, forgot to send to the list. Le 3 juil. 2015 =C3=A0 16:01, Stefan Radomski = <[email protected] = <mailto:[email protected]>> a =C3=A9crit : >=20 > [explicitly bcc'ing David, Jacob and Zjnue for I know that they = maintain SCXML implementations] - this post is pertaining to action = point 1 from my previous mail: >=20 > 1. An Interface Description Language (IDL) for SCXML interpreters. You can keep your various FromXXX methods as optional, but please allow = an overloaded constructor for languages that aren't JAVA :p So, define the constructor's behavior for DOM, XML string, and URI = arguments, leaving room for other types (e.g. File in JSSC). > 1.1 For simple life-cycle and interpretation of state-charts. > 1.2 A set of hooks for (on-line) visualisation. > 1.3 A set of hooks for (on-line) modelling / debugging. >=20 > For now, I'd like to focus on point 1.1, but we ought to keep the = others in mind and maybe eventually extend our ambitions. At least 1.2 = is very useful as it would allow or a common visualisation. I hereby = propose a first sketch for an Interface Description Language (IDL) for = SCXML (see below). It will only allow to instantiate interpreters, run = them and deliver events. A typical session would look like this: >=20 > import namespace scxml; > try { > Interpreter session =3D Implementation.fromURI("http://www = <http://www/>.example.com/foo.scxml <http://example.com/foo.scxml>"); > for(;;) { > int state =3D session.step(); > if (state =3D=3D FINISHED) > break; > if (state =3D=3D AFTER_MACROSTEP && session.configuration.in('foo')) > session.receive('bar.baz'); > } > } catch (Exception e) { > print e; > } That may be "typical" but it's impossible in EcmaScript, which has very = few blocking calls. > =3D=3D 1. Threads > I want to avoid any assumptions about the availability of threads in = the embedding platform. As such, there is e.g. no non-blocking = interpret(). It would be the responsibility of the target platform to = emulate something like this by embedding the block above in a thread. ECMAScript itself does not use threads. However, the APIs and libraries = it can use tend to use threads internally (e.g. network, filesystem, = data encoding/decoding=E2=80=A6) and the language deals with it by using = callbacks, often wrapped in event handlers or Promises. As a result, a typical ECMAScript session would look more like: require(SCXML) session =3D new SCXML("foo.scxml") session.ready.then(session.start.bind(session)) session.on("step", () =3D> { if(session.configuration.has('foo')) = session.receive('bar.baz') }) I suggest specifying both a blocking IDL and a Promise one, = implementations being free to implement either (but not both at once = because methdos would have the same name), and an Event IDL (which can = work with both). E.g in async mode a method like step() returns a Promise that resolves = when the macrostep is done. In blocking mode it returns when the = macrostep is done. We can't have both. Don't even think of stepAsync(). = An implementation that supports both might allow some configuration to = switch modes, but really, I don't see it being useful. And in either = case you could have session.on("done"). > =3D=3D 2. Exceptions > Similarly I want to avoid any assumption about the availability of = exceptions, therefore step() might return FAULT and set the lastError = attribute: >=20 > int state; > for(;;) { > state - session.step(); > switch(state) { > case FAULT: > print session.lastError; > break; > case FINISHED: > return; > } > } Again, the assumption that blocking is always available is false. As = before, write a blocking IDL, a Promise IDL (Promises can reject with an = error), and an event IDL with on("error") conditions. > =3D=3D 3. Data > 0. If nothing in a Data object is set, its value is undefined OK. > 1. If an atom is given, the respective field is to be interpreted as = the evaluation of that atom, e.g. "3" is a string, 3 is an integer. evaluation how? JSON? how about an optional type attribute on <content> = / <data> that I've suggested before? > 2. If a node is given and 1. is not the case, the field is to be = represented as a DOM Node How about multiple node children? > 3. If a key in a compound is set and 1. and 2. are not the case, the = respective field is a map Can you give an example for that one? > 4. If an index is set and none of the above applies, the respective = field is an array. Setting a an item at an index N will cause the array = to behave as if it has N fields for the largest N. With all unset fields = undefined. What's the difference between indices and keys? In ES, indices are just = positive integer keys. I'd say that an array is when you have multiple children with no = keys/indices at all. > =3D=3D 6. Naming > AFTER_MACROSTEP might just as well be called STABLE. I choose the = former for its more explicit reference to the runtime semantics of = SCXML, which might play a role if we were to specify a bunch of hooks = for 1.2 and 1.3 (see debugger paper[1], table 1) I feel that "stable" should be used only when the queue is empty. = Otherwise it's not going to remain stable even one moment. Sorry, I'll have to continue later. David --Apple-Mail=_667083EC-150B-4DAA-A55A-FF964E63F47A Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 <html><head><meta http-equiv=3D"Content-Type" content=3D"text/html = charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" = class=3D"">Sorry, forgot to send to the list.<br class=3D""><div><br = class=3D""><div class=3D""><div class=3D"">Le 3 juil. 2015 =C3=A0 16:01, = Stefan Radomski <<a = href=3D"mailto:[email protected]" = class=3D"">[email protected]</a>> a =C3=A9crit = :</div><div class=3D""><div style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" = class=3D""><div class=3D""><blockquote type=3D"cite" class=3D""><br = class=3D"Apple-interchange-newline"><div class=3D""> <meta http-equiv=3D"Content-Type" content=3D"text/html; = charset=3Dus-ascii" class=3D""> <div style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; = -webkit-line-break: after-white-space;" class=3D"">[explicitly bcc'ing = David, Jacob and Zjnue for I know that they maintain SCXML = implementations] - this post is pertaining to action point 1 from my = previous mail:<br class=3D""> <br class=3D""> 1. An Interface Description Language (IDL) for SCXML interpreters.<br = class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">You can keep your various FromXXX = methods as optional, but please allow an overloaded constructor for = languages that aren't JAVA :p</div><div class=3D"">So, define the = constructor's behavior for DOM, XML string, and URI arguments, leaving = room for other types (e.g. File in JSSC).</div><div class=3D""><br = class=3D""></div><br class=3D""><blockquote type=3D"cite" class=3D""><div = class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: = space; -webkit-line-break: after-white-space;" class=3D""> 1.1 For simple life-cycle and interpretation of state-charts.<br = class=3D""> 1.2 A set of hooks for (on-line) visualisation.<br class=3D""> 1.3 A set of hooks for (on-line) modelling / debugging.<br class=3D""> <br class=3D""> For now, I'd like to focus on point 1.1, but we ought to keep the others = in mind and maybe eventually extend our ambitions. At least 1.2 is very = useful as it would allow or a common visualisation. I hereby propose a = first sketch for an Interface Description Language (IDL) for SCXML (see below). It will only allow to = instantiate interpreters, run them and deliver events. A typical session = would look like this:<br class=3D""> <br class=3D""> import namespace scxml;<br class=3D""> try {<br class=3D""> <span class=3D"Apple-tab-span" = style=3D"white-space:pre"></span>Interpreter session =3D = Implementation.fromURI("<a href=3D"http://www/" = class=3D"">http://www</a>.<a href=3D"http://example.com/foo.scxml" = class=3D"">example.com/foo.scxml</a>");<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>for(;;) = {<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>int = state =3D session.step();<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if = (state =3D=3D FINISHED)<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br = class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>if = (state =3D=3D AFTER_MACROSTEP && = session.configuration.in('foo'))<br class=3D""> <span class=3D"Apple-tab-span" = style=3D"white-space:pre"></span>session.receive('bar.baz');<br = class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br = class=3D""> } catch (Exception e) {<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print = e;<br class=3D""> }<br class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">That may be "typical" but it's = impossible in EcmaScript, which has very few blocking calls.</div><div = class=3D""><br class=3D""></div><br class=3D""><blockquote type=3D"cite" = class=3D""><div class=3D""><div style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" = class=3D"">=3D=3D 1. Threads<br class=3D""> I want to avoid any assumptions about the availability of threads in the = embedding platform. As such, there is e.g. no non-blocking interpret(). = It would be the responsibility of the target platform to emulate = something like this by embedding the block above in a thread.<br class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">ECMAScript itself does not use threads. = However, the APIs and libraries it can use tend to use threads = internally (e.g. network, filesystem, data encoding/decoding=E2=80=A6) = and the language deals with it by using callbacks, often wrapped in = event handlers or Promises.</div><div class=3D""><br class=3D""></div><div= class=3D"">As a result, a typical ECMAScript session would look more = like:</div><div class=3D""><br class=3D""></div><div = class=3D"">require(SCXML)</div><div class=3D""><br class=3D""></div><div = class=3D"">session =3D new SCXML("foo.scxml")<span = id=3D"x-apple-selection:end" class=3D""></span></div><div = class=3D"">session.ready.then(session.start.bind(session))</div><div = class=3D"">session.on("step", () =3D> { = if(session.configuration.has('foo')) session.receive('bar.baz') = })</div><div class=3D""><br class=3D""></div><div class=3D"">I suggest = specifying both a blocking IDL and a Promise one, implementations being = free to implement either (but not both at once because methdos would = have the same name), and an Event IDL (which can work with = both).</div><div class=3D""><br class=3D""></div><div class=3D"">E.g in = async mode a method like step() returns a Promise that resolves when the = macrostep is done. In blocking mode it returns when the macrostep is = done. We can't have both. Don't even think of stepAsync(). An = implementation that supports both might allow some configuration to = switch modes, but really, I don't see it being useful. And in either = case you could have session.on("done").</div><div class=3D""><br = class=3D""></div><div class=3D""><br class=3D""></div><blockquote = type=3D"cite" class=3D""><div class=3D""><div style=3D"word-wrap: = break-word; -webkit-nbsp-mode: space; -webkit-line-break: = after-white-space;" class=3D"">=3D=3D 2. Exceptions<br class=3D""> Similarly I want to avoid any assumption about the availability of = exceptions, therefore step() might return FAULT and set the lastError = attribute:<br class=3D""> <br class=3D""> int state;<br class=3D""> for(;;) {<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>state - = session.step();<br class=3D""> <span class=3D"Apple-tab-span" = style=3D"white-space:pre"></span>switch(state) {<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case = FAULT:<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>print = session.lastError;<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>break;<br = class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>case = FINISHED:<br class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>return;<br= class=3D""> <span class=3D"Apple-tab-span" style=3D"white-space:pre"></span>}<br = class=3D""> }<br class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">Again, the assumption that blocking is = always available is false. As before, write a blocking IDL, a Promise = IDL (Promises can reject with an error), and an event IDL with = on("error") conditions.</div><div class=3D""><br class=3D""></div><div = class=3D""><br class=3D""></div><blockquote type=3D"cite" class=3D""><div = class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: = space; -webkit-line-break: after-white-space;" class=3D""> =3D=3D 3. Data<br class=3D""> 0. If nothing in a Data object is set, its value is = undefined</div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">OK.</div><br class=3D""><blockquote = type=3D"cite" class=3D""><div class=3D""><div style=3D"word-wrap: = break-word; -webkit-nbsp-mode: space; -webkit-line-break: = after-white-space;" class=3D""> 1. If an atom is given, the respective field is to be interpreted as the = evaluation of that atom, e.g. "3" is a string, 3 is an integer.<br = class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">evaluation how? JSON? how about an = optional type attribute on <content> / <data> that I've = suggested before?</div><br class=3D""><blockquote type=3D"cite" = class=3D""><div class=3D""><div style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" = class=3D""> 2. If a node is given and 1. is not the case, the field is to be = represented as a DOM Node</div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">How about multiple node = children?</div><br class=3D""><blockquote type=3D"cite" class=3D""><div = class=3D""><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: = space; -webkit-line-break: after-white-space;" class=3D""> 3. If a key in a compound is set and 1. and 2. are not the case, the = respective field is a map<br class=3D""></div></div></blockquote><div = class=3D""><br class=3D""></div><div class=3D"">Can you give an example = for that one?</div><br class=3D""><blockquote type=3D"cite" = class=3D""><div class=3D""><div style=3D"word-wrap: break-word; = -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" = class=3D""> 4. If an index is set and none of the above applies, the respective = field is an array. Setting a an item at an index N will cause the array = to behave as if it has N fields for the largest N. With all unset fields = undefined.<br class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">What's the difference between indices = and keys? In ES, indices are just positive integer keys.</div><div = class=3D"">I'd say that an array is when you have multiple children with = no keys/indices at all.</div><div class=3D""><br = class=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D""><div= style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; = -webkit-line-break: after-white-space;" class=3D"">=3D=3D 6. Naming<br = class=3D""> AFTER_MACROSTEP might just as well be called STABLE. I choose the former = for its more explicit reference to the runtime semantics of SCXML, which = might play a role if we were to specify a bunch of hooks for 1.2 and 1.3 = (see debugger paper[1], table 1)<br = class=3D""></div></div></blockquote><div class=3D""><br = class=3D""></div><div class=3D"">I feel that "stable" should be used = only when the queue is empty. Otherwise it's not going to remain stable = even one moment.</div><div class=3D""><br class=3D""></div><br = class=3D""></div><div class=3D"">Sorry, I'll have to continue = later.</div><div class=3D""><br class=3D""></div><br class=3D""><div = class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre"> = </span>David</div></div></div></div></div><br = class=3D""></body></html>= --Apple-Mail=_667083EC-150B-4DAA-A55A-FF964E63F47A--