They have little memory, unhurried processors, and are slow in communication but are also small and energy efficient.
%Hence they require additional care.
-A solution is found in \gls{TOP}.
+\Gls{TOP} can cope with the challenges of \gls{IOT} programming.
In \gls{TOP}, the main building blocks are tasks, an abstract representation of work.
During execution, the current value of the task is observable, and other tasks can act upon it.
Collaboration patterns can be modelled by combining and transforming tasks into compound tasks.
-From this high-level declarative description of the work, a ready-for-work tierless application is generated that guides all operators in doing the work.
-An example of a \gls{TOP} system is \gls{ITASK}, a language which describes interactive web applications.
-Programming edge devices benefits from \gls{TOP} as well.
-However, it is not straightforward to run \gls{TOP} systems on edge devices.
+Programming edge devices benefits from \gls{TOP} as well, but running such a system within the limitations of resource-constrained microcontrollers is not straightforward.
This dissertation demonstrates how to include edge devices in \gls{TOP} systems using \glspl{DSL}.
With these techniques, all tiers and their interoperation of an \gls{IOT} system is specified in a single high-level source, language, paradigm, high abstraction level, and type system.
Then \gls{MTASK} is shown, a \gls{TOP} \gls{DSL} for \gls{IOT} edge devices, embedded in \gls{ITASK}.
Tasks are constructed and compiled at run time in order to allow tasks to be tailored to the current work requirements.
The task is then sent to the device for interpretation.
-For a device to be used in an \gls{MTASK} system, it is programmed once with a lightweight domain-specific \gls{OS}.
+A device is programmed once with a lightweight domain-specific \gls{OS} to be used in an \gls{MTASK} system.
This \gls{OS} executes tasks in an energy-efficient way and automates all communications and data sharing.
All aspects of the \gls{MTASK} system are shown: example applications, language design, implementation details, integration with \gls{ITASK}, and green computing facilities such as automatic sleeping.
-Finally, tierless programming is compared to traditional tiered programming.
-It demonstrates that when using tierless programming frameworks, the size of the code and the number of required programming languages and paradigms is reduced significantly.
-Furthermore, tierless programming reduces problems such semantic friction; maintainability and robustness issues; and interoperation safety.
+Finally, tierless \gls{IOT} programming is compared to traditional tiered programming.
+In tierless programming frameworks, the size of the code and the number of required programming languages is reduced significantly.
+By using a single paradigm and a system-wide type system, tierless programming reduces problems such semantic friction; maintainability and robustness issues; and interoperation safety.
%This is a summary of 350--400 words.
\end{document}
+++ /dev/null
-%% File: `abbrvnat.bst'
-%% A modification of `abbrv.bst' for use with natbib package
-%%
-%% Copyright 1993-2007 Patrick W Daly
-%% Max-Planck-Institut f\"ur Sonnensystemforschung
-%% Max-Planck-Str. 2
-%% D-37191 Katlenburg-Lindau
-%% Germany
-%% E-mail: daly@mps.mpg.de
-%%
-%% This program can be redistributed and/or modified under the terms
-%% of the LaTeX Project Public License Distributed from CTAN
-%% archives in directory macros/latex/base/lppl.txt; either
-%% version 1 of the License, or any later version.
-%%
- % Version and source file information:
- % \ProvidesFile{natbst.mbs}[2007/11/26 1.93 (PWD)]
- %
- % BibTeX `plainnat' family
- % version 0.99b for BibTeX versions 0.99a or later,
- % for LaTeX versions 2.09 and 2e.
- %
- % For use with the `natbib.sty' package; emulates the corresponding
- % member of the `plain' family, but with author-year citations.
- %
- % With version 6.0 of `natbib.sty', it may also be used for numerical
- % citations, while retaining the commands \citeauthor, \citefullauthor,
- % and \citeyear to print the corresponding information.
- %
- % For version 7.0 of `natbib.sty', the KEY field replaces missing
- % authors/editors, and the date is left blank in \bibitem.
- %
- % Includes field EID for the sequence/citation number of electronic journals
- % which is used instead of page numbers.
- %
- % Includes fields ISBN and ISSN.
- %
- % Includes field URL for Internet addresses.
- %
- % Includes field DOI for Digital Object Idenfifiers.
- %
- % Works best with the url.sty package of Donald Arseneau.
- %
- % Works with identical authors and year are further sorted by
- % citation key, to preserve any natural sequence.
- %
-ENTRY
- { address
- author
- booktitle
- chapter
- doi
- eid
- edition
- editor
- howpublished
- institution
- isbn
- issn
- journal
- key
- month
- note
- number
- organization
- pages
- publisher
- school
- series
- title
- type
- url
- urldate
- volume
- year
- }
- {}
- { label extra.label sort.label short.list }
-
-INTEGERS { output.state before.all mid.sentence after.sentence after.block }
-
-FUNCTION {init.state.consts}
-{ #0 'before.all :=
- #1 'mid.sentence :=
- #2 'after.sentence :=
- #3 'after.block :=
-}
-
-STRINGS { s t }
-
-FUNCTION {output.nonnull}
-{ 's :=
- output.state mid.sentence =
- { ", " * write$ }
- { output.state after.block =
- { add.period$ write$
- newline$
- "\newblock " write$
- }
- { output.state before.all =
- 'write$
- { add.period$ " " * write$ }
- if$
- }
- if$
- mid.sentence 'output.state :=
- }
- if$
- s
-}
-
-FUNCTION {output}
-{ duplicate$ empty$
- 'pop$
- 'output.nonnull
- if$
-}
-
-FUNCTION {output.check}
-{ 't :=
- duplicate$ empty$
- { pop$ "empty " t * " in " * cite$ * warning$ }
- 'output.nonnull
- if$
-}
-
-FUNCTION {fin.entry}
-{ add.period$
- write$
- newline$
-}
-
-FUNCTION {new.block}
-{ output.state before.all =
- 'skip$
- { after.block 'output.state := }
- if$
-}
-
-FUNCTION {new.sentence}
-{ output.state after.block =
- 'skip$
- { output.state before.all =
- 'skip$
- { after.sentence 'output.state := }
- if$
- }
- if$
-}
-
-FUNCTION {not}
-{ { #0 }
- { #1 }
- if$
-}
-
-FUNCTION {and}
-{ 'skip$
- { pop$ #0 }
- if$
-}
-
-FUNCTION {or}
-{ { pop$ #1 }
- 'skip$
- if$
-}
-
-FUNCTION {new.block.checka}
-{ empty$
- 'skip$
- 'new.block
- if$
-}
-
-FUNCTION {new.block.checkb}
-{ empty$
- swap$ empty$
- and
- 'skip$
- 'new.block
- if$
-}
-
-FUNCTION {new.sentence.checka}
-{ empty$
- 'skip$
- 'new.sentence
- if$
-}
-
-FUNCTION {new.sentence.checkb}
-{ empty$
- swap$ empty$
- and
- 'skip$
- 'new.sentence
- if$
-}
-
-FUNCTION {field.or.null}
-{ duplicate$ empty$
- { pop$ "" }
- 'skip$
- if$
-}
-
-FUNCTION {emphasize}
-{ duplicate$ empty$
- { pop$ "" }
- { "\emph{" swap$ * "}" * }
- if$
-}
-
-INTEGERS { nameptr namesleft numnames }
-
-FUNCTION {format.names}
-{ 's :=
- #1 'nameptr :=
- s num.names$ 'numnames :=
- numnames 'namesleft :=
- { namesleft #0 > }
- { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't :=
- nameptr #1 >
- { namesleft #1 >
- { ", " * t * }
- { numnames #2 >
- { "," * }
- 'skip$
- if$
- t "others" =
- { " et~al." * }
- { " and " * t * }
- if$
- }
- if$
- }
- 't
- if$
- nameptr #1 + 'nameptr :=
- namesleft #1 - 'namesleft :=
- }
- while$
-}
-
-FUNCTION {format.key}
-{ empty$
- { key field.or.null }
- { "" }
- if$
-}
-
-FUNCTION {format.authors}
-{ author empty$
- { "" }
- { author format.names }
- if$
-}
-
-FUNCTION {format.editors}
-{ editor empty$
- { "" }
- { editor format.names
- editor num.names$ #1 >
- { ", editors" * }
- { ", editor" * }
- if$
- }
- if$
-}
-
-FUNCTION {format.isbn}
-{ isbn empty$
- { "" }
- { new.block "ISBN " isbn * }
- if$
-}
-
-FUNCTION {format.issn}
-{ issn empty$
- { "" }
- { new.block "ISSN " issn * }
- if$
-}
-
-FUNCTION {format.url}
-{ url empty$
- { "" }
- { new.block "URL \url{" url * "}" * }
- if$
-}
-FUNCTION {format.urldate}
-{ urldate empty$
- { "" }
- {new.block "accessed-on: " urldate * }
- if$
-}
-
-FUNCTION {format.doi}
-{ doi empty$
- { "" }
- { new.block "\doi{" doi * "}" * }
- if$
-}
-
-FUNCTION {format.title}
-{ title empty$
- { "" }
- { title "t" change.case$ }
- if$
-}
-
-FUNCTION {format.full.names}
-{'s :=
- #1 'nameptr :=
- s num.names$ 'numnames :=
- numnames 'namesleft :=
- { namesleft #0 > }
- { s nameptr
- "{vv~}{ll}" format.name$ 't :=
- nameptr #1 >
- {
- namesleft #1 >
- { ", " * t * }
- {
- numnames #2 >
- { "," * }
- 'skip$
- if$
- t "others" =
- { " et~al." * }
- { " and " * t * }
- if$
- }
- if$
- }
- 't
- if$
- nameptr #1 + 'nameptr :=
- namesleft #1 - 'namesleft :=
- }
- while$
-}
-
-FUNCTION {author.editor.full}
-{ author empty$
- { editor empty$
- { "" }
- { editor format.full.names }
- if$
- }
- { author format.full.names }
- if$
-}
-
-FUNCTION {author.full}
-{ author empty$
- { "" }
- { author format.full.names }
- if$
-}
-
-FUNCTION {editor.full}
-{ editor empty$
- { "" }
- { editor format.full.names }
- if$
-}
-
-FUNCTION {make.full.names}
-{ type$ "book" =
- type$ "inbook" =
- or
- 'author.editor.full
- { type$ "proceedings" =
- 'editor.full
- 'author.full
- if$
- }
- if$
-}
-
-FUNCTION {output.bibitem}
-{ newline$
- "\bibitem[" write$
- label write$
- ")" make.full.names duplicate$ short.list =
- { pop$ }
- { * }
- if$
- "]{" * write$
- cite$ write$
- "}" write$
- newline$
- ""
- before.all 'output.state :=
-}
-
-FUNCTION {n.dashify}
-{ 't :=
- ""
- { t empty$ not }
- { t #1 #1 substring$ "-" =
- { t #1 #2 substring$ "--" = not
- { "--" *
- t #2 global.max$ substring$ 't :=
- }
- { { t #1 #1 substring$ "-" = }
- { "-" *
- t #2 global.max$ substring$ 't :=
- }
- while$
- }
- if$
- }
- { t #1 #1 substring$ *
- t #2 global.max$ substring$ 't :=
- }
- if$
- }
- while$
-}
-
-FUNCTION {format.date}
-{ year duplicate$ empty$
- { "empty year in " cite$ * warning$
- pop$ "" }
- 'skip$
- if$
- month empty$
- 'skip$
- { month
- " " * swap$ *
- }
- if$
- extra.label *
-}
-
-FUNCTION {format.btitle}
-{ title emphasize
-}
-
-FUNCTION {tie.or.space.connect}
-{ duplicate$ text.length$ #3 <
- { "~" }
- { " " }
- if$
- swap$ * *
-}
-
-FUNCTION {either.or.check}
-{ empty$
- 'pop$
- { "can't use both " swap$ * " fields in " * cite$ * warning$ }
- if$
-}
-
-FUNCTION {format.bvolume}
-{ volume empty$
- { "" }
- { "volume" volume tie.or.space.connect
- series empty$
- 'skip$
- { " of " * series emphasize * }
- if$
- "volume and number" number either.or.check
- }
- if$
-}
-
-FUNCTION {format.number.series}
-{ volume empty$
- { number empty$
- { series field.or.null }
- { output.state mid.sentence =
- { "number" }
- { "Number" }
- if$
- number tie.or.space.connect
- series empty$
- { "there's a number but no series in " cite$ * warning$ }
- { " in " * series * }
- if$
- }
- if$
- }
- { "" }
- if$
-}
-
-FUNCTION {format.edition}
-{ edition empty$
- { "" }
- { output.state mid.sentence =
- { edition "l" change.case$ " edition" * }
- { edition "t" change.case$ " edition" * }
- if$
- }
- if$
-}
-
-INTEGERS { multiresult }
-
-FUNCTION {multi.page.check}
-{ 't :=
- #0 'multiresult :=
- { multiresult not
- t empty$ not
- and
- }
- { t #1 #1 substring$
- duplicate$ "-" =
- swap$ duplicate$ "," =
- swap$ "+" =
- or or
- { #1 'multiresult := }
- { t #2 global.max$ substring$ 't := }
- if$
- }
- while$
- multiresult
-}
-
-FUNCTION {format.pages}
-{ pages empty$
- { "" }
- { pages multi.page.check
- { "pages" pages n.dashify tie.or.space.connect }
- { "page" pages tie.or.space.connect }
- if$
- }
- if$
-}
-
-FUNCTION {format.eid}
-{ eid empty$
- { "" }
- { "art." eid tie.or.space.connect }
- if$
-}
-
-FUNCTION {format.vol.num.pages}
-{ volume field.or.null
- number empty$
- 'skip$
- { "\penalty0 (" number * ")" * *
- volume empty$
- { "there's a number but no volume in " cite$ * warning$ }
- 'skip$
- if$
- }
- if$
- pages empty$
- 'skip$
- { duplicate$ empty$
- { pop$ format.pages }
- { ":\penalty0 " * pages n.dashify * }
- if$
- }
- if$
-}
-
-FUNCTION {format.vol.num.eid}
-{ volume field.or.null
- number empty$
- 'skip$
- { "\penalty0 (" number * ")" * *
- volume empty$
- { "there's a number but no volume in " cite$ * warning$ }
- 'skip$
- if$
- }
- if$
- eid empty$
- 'skip$
- { duplicate$ empty$
- { pop$ format.eid }
- { ":\penalty0 " * eid * }
- if$
- }
- if$
-}
-
-FUNCTION {format.chapter.pages}
-{ chapter empty$
- 'format.pages
- { type empty$
- { "chapter" }
- { type "l" change.case$ }
- if$
- chapter tie.or.space.connect
- pages empty$
- 'skip$
- { ", " * format.pages * }
- if$
- }
- if$
-}
-
-FUNCTION {format.in.ed.booktitle}
-{ booktitle empty$
- { "" }
- { editor empty$
- { "In " booktitle emphasize * }
- { "In " format.editors * ", " * booktitle emphasize * }
- if$
- }
- if$
-}
-
-FUNCTION {empty.misc.check}
-{ author empty$ title empty$ howpublished empty$
- month empty$ year empty$ note empty$
- and and and and and
- key empty$ not and
- { "all relevant fields are empty in " cite$ * warning$ }
- 'skip$
- if$
-}
-
-FUNCTION {format.thesis.type}
-{ type empty$
- 'skip$
- { pop$
- type "t" change.case$
- }
- if$
-}
-
-FUNCTION {format.tr.number}
-{ type empty$
- { "Technical Report" }
- 'type
- if$
- number empty$
- { "t" change.case$ }
- { number tie.or.space.connect }
- if$
-}
-
-FUNCTION {format.article.crossref}
-{ key empty$
- { journal empty$
- { "need key or journal for " cite$ * " to crossref " * crossref *
- warning$
- ""
- }
- { "In \emph{" journal * "}" * }
- if$
- }
- { "In " }
- if$
- " \citet{" * crossref * "}" *
-}
-
-FUNCTION {format.book.crossref}
-{ volume empty$
- { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
- "In "
- }
- { "Volume" volume tie.or.space.connect
- " of " *
- }
- if$
- editor empty$
- editor field.or.null author field.or.null =
- or
- { key empty$
- { series empty$
- { "need editor, key, or series for " cite$ * " to crossref " *
- crossref * warning$
- "" *
- }
- { "\emph{" * series * "}" * }
- if$
- }
- 'skip$
- if$
- }
- 'skip$
- if$
- " \citet{" * crossref * "}" *
-}
-
-FUNCTION {format.incoll.inproc.crossref}
-{ editor empty$
- editor field.or.null author field.or.null =
- or
- { key empty$
- { booktitle empty$
- { "need editor, key, or booktitle for " cite$ * " to crossref " *
- crossref * warning$
- ""
- }
- { "In \emph{" booktitle * "}" * }
- if$
- }
- { "In " }
- if$
- }
- { "In " }
- if$
- " \citet{" * crossref * "}" *
-}
-
-FUNCTION {article}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- crossref missing$
- { journal emphasize "journal" output.check
- eid empty$
- { format.vol.num.pages output }
- { format.vol.num.eid output }
- if$
- format.date "year" output.check
- }
- { format.article.crossref output.nonnull
- eid empty$
- { format.pages output }
- { format.eid output }
- if$
- }
- if$
- format.issn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {book}
-{ output.bibitem
- author empty$
- { format.editors "author and editor" output.check
- editor format.key output
- }
- { format.authors output.nonnull
- crossref missing$
- { "author and editor" editor either.or.check }
- 'skip$
- if$
- }
- if$
- new.block
- format.btitle "title" output.check
- crossref missing$
- { format.bvolume output
- new.block
- format.number.series output
- new.sentence
- publisher "publisher" output.check
- address output
- }
- { new.block
- format.book.crossref output.nonnull
- }
- if$
- format.edition output
- format.date "year" output.check
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {booklet}
-{ output.bibitem
- format.authors output
- author format.key output
- new.block
- format.title "title" output.check
- howpublished address new.block.checkb
- howpublished output
- address output
- format.date output
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {inbook}
-{ output.bibitem
- author empty$
- { format.editors "author and editor" output.check
- editor format.key output
- }
- { format.authors output.nonnull
- crossref missing$
- { "author and editor" editor either.or.check }
- 'skip$
- if$
- }
- if$
- new.block
- format.btitle "title" output.check
- crossref missing$
- { format.bvolume output
- format.chapter.pages "chapter and pages" output.check
- new.block
- format.number.series output
- new.sentence
- publisher "publisher" output.check
- address output
- }
- { format.chapter.pages "chapter and pages" output.check
- new.block
- format.book.crossref output.nonnull
- }
- if$
- format.edition output
- format.date "year" output.check
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {incollection}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- crossref missing$
- { format.in.ed.booktitle "booktitle" output.check
- format.bvolume output
- format.number.series output
- format.chapter.pages output
- new.sentence
- publisher "publisher" output.check
- address output
- format.edition output
- format.date "year" output.check
- }
- { format.incoll.inproc.crossref output.nonnull
- format.chapter.pages output
- }
- if$
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {inproceedings}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- crossref missing$
- { format.in.ed.booktitle "booktitle" output.check
- format.bvolume output
- format.number.series output
- format.pages output
- address empty$
- { organization publisher new.sentence.checkb
- organization output
- publisher output
- format.date "year" output.check
- }
- { address output.nonnull
- format.date "year" output.check
- new.sentence
- organization output
- publisher output
- }
- if$
- }
- { format.incoll.inproc.crossref output.nonnull
- format.pages output
- }
- if$
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {conference} { inproceedings }
-
-FUNCTION {manual}
-{ output.bibitem
- format.authors output
- author format.key output
- new.block
- format.btitle "title" output.check
- organization address new.block.checkb
- organization output
- address output
- format.edition output
- format.date output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {mastersthesis}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- "Master's thesis" format.thesis.type output.nonnull
- school "school" output.check
- address output
- format.date "year" output.check
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {misc}
-{ output.bibitem
- format.authors output
- author format.key output
- title howpublished new.block.checkb
- format.title output
- howpublished new.block.checka
- howpublished output
- format.date output
- format.issn output
- format.url output
- new.block
- note output
- format.urldate output
- fin.entry
- empty.misc.check
-}
-
-FUNCTION {phdthesis}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.btitle "title" output.check
- new.block
- "PhD thesis" format.thesis.type output.nonnull
- school "school" output.check
- address output
- format.date "year" output.check
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {proceedings}
-{ output.bibitem
- format.editors output
- editor format.key output
- new.block
- format.btitle "title" output.check
- format.bvolume output
- format.number.series output
- address output
- format.date "year" output.check
- new.sentence
- organization output
- publisher output
- format.isbn output
- format.doi output
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {techreport}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- format.tr.number output.nonnull
- institution "institution" output.check
- address output
- format.date "year" output.check
- format.url output
- new.block
- note output
- fin.entry
-}
-
-FUNCTION {unpublished}
-{ output.bibitem
- format.authors "author" output.check
- author format.key output
- new.block
- format.title "title" output.check
- new.block
- note "note" output.check
- format.date output
- format.url output
- fin.entry
-}
-
-FUNCTION {default.type} { misc }
-
-
-MACRO {jan} {"Jan."}
-
-MACRO {feb} {"Feb."}
-
-MACRO {mar} {"Mar."}
-
-MACRO {apr} {"Apr."}
-
-MACRO {may} {"May"}
-
-MACRO {jun} {"June"}
-
-MACRO {jul} {"July"}
-
-MACRO {aug} {"Aug."}
-
-MACRO {sep} {"Sept."}
-
-MACRO {oct} {"Oct."}
-
-MACRO {nov} {"Nov."}
-
-MACRO {dec} {"Dec."}
-
-
-
-MACRO {acmcs} {"ACM Comput. Surv."}
-
-MACRO {acta} {"Acta Inf."}
-
-MACRO {cacm} {"Commun. ACM"}
-
-MACRO {ibmjrd} {"IBM J. Res. Dev."}
-
-MACRO {ibmsj} {"IBM Syst.~J."}
-
-MACRO {ieeese} {"IEEE Trans. Softw. Eng."}
-
-MACRO {ieeetc} {"IEEE Trans. Comput."}
-
-MACRO {ieeetcad}
- {"IEEE Trans. Comput.-Aided Design Integrated Circuits"}
-
-MACRO {ipl} {"Inf. Process. Lett."}
-
-MACRO {jacm} {"J.~ACM"}
-
-MACRO {jcss} {"J.~Comput. Syst. Sci."}
-
-MACRO {scp} {"Sci. Comput. Programming"}
-
-MACRO {sicomp} {"SIAM J. Comput."}
-
-MACRO {tocs} {"ACM Trans. Comput. Syst."}
-
-MACRO {tods} {"ACM Trans. Database Syst."}
-
-MACRO {tog} {"ACM Trans. Gr."}
-
-MACRO {toms} {"ACM Trans. Math. Softw."}
-
-MACRO {toois} {"ACM Trans. Office Inf. Syst."}
-
-MACRO {toplas} {"ACM Trans. Prog. Lang. Syst."}
-
-MACRO {tcs} {"Theoretical Comput. Sci."}
-
-
-READ
-
-FUNCTION {sortify}
-{ purify$
- "l" change.case$
-}
-
-INTEGERS { len }
-
-FUNCTION {chop.word}
-{ 's :=
- 'len :=
- s #1 len substring$ =
- { s len #1 + global.max$ substring$ }
- 's
- if$
-}
-
-FUNCTION {format.lab.names}
-{ 's :=
- s #1 "{vv~}{ll}" format.name$
- s num.names$ duplicate$
- #2 >
- { pop$ " et~al." * }
- { #2 <
- 'skip$
- { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
- { " et~al." * }
- { " and " * s #2 "{vv~}{ll}" format.name$ * }
- if$
- }
- if$
- }
- if$
-}
-
-FUNCTION {author.key.label}
-{ author empty$
- { key empty$
- { cite$ #1 #3 substring$ }
- 'key
- if$
- }
- { author format.lab.names }
- if$
-}
-
-FUNCTION {author.editor.key.label}
-{ author empty$
- { editor empty$
- { key empty$
- { cite$ #1 #3 substring$ }
- 'key
- if$
- }
- { editor format.lab.names }
- if$
- }
- { author format.lab.names }
- if$
-}
-
-FUNCTION {author.key.organization.label}
-{ author empty$
- { key empty$
- { organization empty$
- { cite$ #1 #3 substring$ }
- { "The " #4 organization chop.word #3 text.prefix$ }
- if$
- }
- 'key
- if$
- }
- { author format.lab.names }
- if$
-}
-
-FUNCTION {editor.key.organization.label}
-{ editor empty$
- { key empty$
- { organization empty$
- { cite$ #1 #3 substring$ }
- { "The " #4 organization chop.word #3 text.prefix$ }
- if$
- }
- 'key
- if$
- }
- { editor format.lab.names }
- if$
-}
-
-FUNCTION {calc.short.authors}
-{ type$ "book" =
- type$ "inbook" =
- or
- 'author.editor.key.label
- { type$ "proceedings" =
- 'editor.key.organization.label
- { type$ "manual" =
- 'author.key.organization.label
- 'author.key.label
- if$
- }
- if$
- }
- if$
- 'short.list :=
-}
-
-FUNCTION {calc.label}
-{ calc.short.authors
- short.list
- "("
- *
- year duplicate$ empty$
- short.list key field.or.null = or
- { pop$ "" }
- 'skip$
- if$
- *
- 'label :=
-}
-
-FUNCTION {sort.format.names}
-{ 's :=
- #1 'nameptr :=
- ""
- s num.names$ 'numnames :=
- numnames 'namesleft :=
- { namesleft #0 > }
- {
- s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't :=
- nameptr #1 >
- {
- " " *
- namesleft #1 = t "others" = and
- { "zzzzz" * }
- { numnames #2 > nameptr #2 = and
- { "zz" * year field.or.null * " " * }
- 'skip$
- if$
- t sortify *
- }
- if$
- }
- { t sortify * }
- if$
- nameptr #1 + 'nameptr :=
- namesleft #1 - 'namesleft :=
- }
- while$
-}
-
-FUNCTION {sort.format.title}
-{ 't :=
- "A " #2
- "An " #3
- "The " #4 t chop.word
- chop.word
- chop.word
- sortify
- #1 global.max$ substring$
-}
-
-FUNCTION {author.sort}
-{ author empty$
- { key empty$
- { "to sort, need author or key in " cite$ * warning$
- ""
- }
- { key sortify }
- if$
- }
- { author sort.format.names }
- if$
-}
-
-FUNCTION {author.editor.sort}
-{ author empty$
- { editor empty$
- { key empty$
- { "to sort, need author, editor, or key in " cite$ * warning$
- ""
- }
- { key sortify }
- if$
- }
- { editor sort.format.names }
- if$
- }
- { author sort.format.names }
- if$
-}
-
-FUNCTION {author.organization.sort}
-{ author empty$
- { organization empty$
- { key empty$
- { "to sort, need author, organization, or key in " cite$ * warning$
- ""
- }
- { key sortify }
- if$
- }
- { "The " #4 organization chop.word sortify }
- if$
- }
- { author sort.format.names }
- if$
-}
-
-FUNCTION {editor.organization.sort}
-{ editor empty$
- { organization empty$
- { key empty$
- { "to sort, need editor, organization, or key in " cite$ * warning$
- ""
- }
- { key sortify }
- if$
- }
- { "The " #4 organization chop.word sortify }
- if$
- }
- { editor sort.format.names }
- if$
-}
-
-
-FUNCTION {presort}
-{ calc.label
- label sortify
- " "
- *
- type$ "book" =
- type$ "inbook" =
- or
- 'author.editor.sort
- { type$ "proceedings" =
- 'editor.organization.sort
- { type$ "manual" =
- 'author.organization.sort
- 'author.sort
- if$
- }
- if$
- }
- if$
- " "
- *
- year field.or.null sortify
- *
- " "
- *
- cite$
- *
- #1 entry.max$ substring$
- 'sort.label :=
- sort.label *
- #1 entry.max$ substring$
- 'sort.key$ :=
-}
-
-ITERATE {presort}
-
-SORT
-
-STRINGS { longest.label last.label next.extra }
-
-INTEGERS { longest.label.width last.extra.num number.label }
-
-FUNCTION {initialize.longest.label}
-{ "" 'longest.label :=
- #0 int.to.chr$ 'last.label :=
- "" 'next.extra :=
- #0 'longest.label.width :=
- #0 'last.extra.num :=
- #0 'number.label :=
-}
-
-FUNCTION {forward.pass}
-{ last.label label =
- { last.extra.num #1 + 'last.extra.num :=
- last.extra.num int.to.chr$ 'extra.label :=
- }
- { "a" chr.to.int$ 'last.extra.num :=
- "" 'extra.label :=
- label 'last.label :=
- }
- if$
- number.label #1 + 'number.label :=
-}
-
-FUNCTION {reverse.pass}
-{ next.extra "b" =
- { "a" 'extra.label := }
- 'skip$
- if$
- extra.label 'next.extra :=
- extra.label
- duplicate$ empty$
- 'skip$
- { "{\natexlab{" swap$ * "}}" * }
- if$
- 'extra.label :=
- label extra.label * 'label :=
-}
-
-EXECUTE {initialize.longest.label}
-
-ITERATE {forward.pass}
-
-REVERSE {reverse.pass}
-
-FUNCTION {bib.sort.order}
-{ sort.label 'sort.key$ :=
-}
-
-ITERATE {bib.sort.order}
-
-SORT
-
-FUNCTION {begin.bib}
-{ preamble$ empty$
- 'skip$
- { preamble$ write$ newline$ }
- if$
- "\begin{thebibliography}{" number.label int.to.str$ * "}" *
- write$ newline$
- "\providecommand{\natexlab}[1]{#1}"
- write$ newline$
- "\providecommand{\url}[1]{\texttt{#1}}"
- write$ newline$
- "\expandafter\ifx\csname urlstyle\endcsname\relax"
- write$ newline$
- " \providecommand{\doi}[1]{doi: #1}\else"
- write$ newline$
- " \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi"
- write$ newline$
-}
-
-EXECUTE {begin.bib}
-
-EXECUTE {init.state.consts}
-
-ITERATE {call.type$}
-
-FUNCTION {end.bib}
-{ newline$
- "\end{thebibliography}" write$ newline$
-}
-
-EXECUTE {end.bib}
\usepackage{microtype} % short arrows
\usepackage{stmaryrd} % short arrows
-%\usepackage{textcomp} % upquote
\usepackage{titlecaps} % titlecase commands
\usepackage{wasysym} % circle symbols
\usepackage{relsize} % \smaller command
\usepackage{xcolor} % colors
\usepackage{fnpct} % footnotekerning
+\usepackage{nicefrac} % footnotekerning
%\usepackage[all]{nowidow} % Kill widows and orphans
\usepackage{siunitx} % typeset units
\item introducing edge device programming;
\item showing how to create the \emph{Hello World!} application for microcontrollers using \gls{ARDUINO} and \gls{MTASK};
\item extending the idea to cooperative multitasking, uncovering problems using \gls{ARDUINO} that do not exist in \gls{MTASK};
- \item and providing a reading guide for the remainder of the monograph.
+ \item and concluding with a reading guide for the remainder of the monograph.
\end{itemize}
\end{chapterabstract}
They differ significantly from regular computers in many aspects.
For example, they are much smaller; only have a fraction of the memory and processor speed; and run on different architectures.
Furthermore, they have much more energy-efficient sleep modes, and support connecting and interfacing with peripherals such as sensors and actuators.
-To illustrate the difference in characteristics, \cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two popular microcontrollers.
-As a consequence of these differences, development for microcontrollers is also unlike development for traditional computers.
-Usually, programming microcontrollers requires an elaborate multistep toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to run a program.
-The software is usually a cyclic executive instead of tasks that run in an \gls{OS}.
+To illustrate the difference in characteristics, \cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop to the characteristics two popular microcontrollers.
+As a consequence of these differences, development for microcontrollers is unlike development for traditional computers.
+Programming microcontrollers requires an elaborate multistep toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to run a program.
+Furthermore, as there is no \gls{OS} to coordinate multiple tasks running at the same time, the software is usually written as a cyclic executive.
Hence, all tasks must be manually combined into a single program.
\begin{table}
Such web applications often form the core of the topmost two layers of \gls{IOT} applications: the presentation and application layer.
Furthermore, \gls{IOT} edge devices are typically programmed with similar workflow-like programs for which \gls{TOP} is very suitable.
Directly incorporating the perception layer, and thus edge devices, in \gls{ITASK} however is not straightforward.
-All \gls{ITASK} applications carry the weigth of multi-user \gls{TOP} programs that can generically generate webpages, communication, and storage for all data types in the program.
-As a result, the \gls{ITASK} system targetting relatively fast and hence energy-hungry systems with large amounts of \gls{RAM} and a speedy connection.
+All \gls{ITASK} applications carry the weight of multi-user \gls{TOP} programs that can generically generate webpages, communication, and storage for all data types in the program.
+As a result, the \gls{ITASK} system targeting relatively fast and hence energy-hungry systems with large amounts of \gls{RAM} and a speedy connection.
Edge devices in \gls{IOT} systems are typically slow but energy efficient and do not have the memory to run the naturally heap-heavy feature-packed functional programs that \gls{ITASK} programs are.
The \gls{MTASK} system bridges this gap by providing a domain-specific \gls{TOP} language for \gls{IOT} edge devices.
Domain-specific knowledge is embedded in the language and execution platform and unnecessary features for edge devices are removed to drastically lower the hardware requirements.
It helps the programmer to become familiarised with the syntax of the language and to verify that the toolchain and runtime environment are working.
Microcontrollers usually do not come with screens in the traditional sense.
Nevertheless, almost always there is a built-in 1 pixel screen with a \qty{1}{\bit} color depth, namely the on-board \gls{LED}.
-The \emph{Hello World!} equivalent on microcontrollers blinks this \gls{LED}.
+The \emph{Hello World!} equivalent for microcontrollers blinks this \gls{LED}.
Creating a blink program using \ccpp{} and the \gls{ARDUINO} libraries result in the code seen in \cref{lst:arduinoBlink}.
\Gls{ARDUINO} programs are implemented as cyclic executives and hence, each program defines a \arduinoinline{setup} and a \arduinoinline{loop} function.
\begin{lstClean}[caption={Blinking the \gls{LED} using a function.},label={lst:blinkFun}]
blinkTask :: Main (MTask v ()) | mtask v
blinkTask = declarePin D2 PMOutput \ledPin->
- fun \blink=(\st->
+ fun \blink = (\st->
writeD ledPin st
>>|. delay (lit 500)
>>|. blink (Not st))
For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of \qtylist{500;300;800}{\ms}.
Intuitively, you would want to lift the blinking behaviour to a function in order to minimise duplicate code, and increase modularity by calling this function three times with different parameters as shown in \cref{lst:blinkthreadno}.
-\begin{lstArduino}[caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}]
+\begin{lstArduino}[float=,caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}]
void setup () { ... }
void blink(int pin, int wait) {
digitalWrite(pin, HIGH);
Unfortunately, this does not work because the \arduinoinline{delay} function blocks all other execution.
The resulting program blinks the \glspl{LED} after each other instead of at the same time.
To overcome this, it is necessary to slice up the blinking behaviour in small fragments and interleave it manually \citep{feijs_multi-tasking_2013}.
-\Cref{lst:blinkthread} shows how three different blinking patterns could be implemented in \gls{ARDUINO} using the slicing method.
-If we want the blink function to be a separate parametrisable function we need to explicitly provide all references to the required global state.
-Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
-The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller.
-If the delay passed to the \arduinoinline{delay} function is long enough, the firmware may decide to put the processor in sleep mode, reducing the power consumption drastically.
-When polling \arduinoinline{millis} is used, this therefore potentially affects power consumption since the processor is busy looping all the time, not knowing when to go to sleep.
-Manually combining tasks into a single modular program is very error-prone, requires a lot of pointer juggling, and generally results into spaghetti code.
-Furthermore, it is very difficult to represent dependencies between threads.
-Often state machines have to be explicitly programmed and merged by hand to achieve this.
-In the simple case of blinking three \glspl{LED} according to fixed intervals, it is possible to calculate the delays in advance using static analysis and generate the appropriate \arduinoinline{delay} calls.
-Unfortunately, this is very hard when for example the blinking patterns are determined at runtime.
-\begin{lstArduino}[label={lst:blinkthread},caption={Threading three blinking patterns.}]
+\begin{lstArduino}[float=,label={lst:blinkthread},caption={Threading three blinking patterns.}]
long led1 = 0, led2 = 0, led3 = 0;
bool st1 = false, st2 = false, st3 = false;
blink(D3, 800, &led3, &st1);
}\end{lstArduino}
+\Cref{lst:blinkthread} shows how three different blinking patterns could be implemented in \gls{ARDUINO} using the slicing method.
+If we want the blink function to be a separate parametrisable function we need to explicitly provide all references to the required global state.
+Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
+The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller.
+If the delay passed to the \arduinoinline{delay} function is long enough, the firmware may decide to put the processor in sleep mode, reducing the power consumption drastically.
+When polling \arduinoinline{millis} is used, this therefore potentially affects power consumption since the processor is busy looping all the time, not knowing when to go to sleep.
+Manually combining tasks into a single modular program is very error-prone, requires a lot of pointer juggling, and generally results into spaghetti code.
+Furthermore, it is very difficult to represent dependencies between threads.
+Often state machines have to be explicitly programmed and merged by hand to achieve this.
+In the simple case of blinking three \glspl{LED} according to fixed intervals, it is possible to calculate the delays in advance using static analysis and generate the appropriate \arduinoinline{delay} calls.
+Unfortunately, this is very hard when for example the blinking patterns are determined at runtime.
+
\subsection{Multitasking in mTask}
In \gls{MTASK}, expressions are eagerly evaluated in an interpreter and tasks are executed by small-step rewrite rules.
-In between these rewrite steps, other tasks are be executed and communication is handled.
+In between these rewrite steps, other tasks are executed and communication is handled.
Consequently, and in contrast to \gls{ARDUINO}, the \cleaninline{delay} task in \gls{MTASK} does not block the execution.
It has no observable value until the target waiting time has passed, and is thence \emph{stable}.
As there is no global state, the function is parametrised with the current status, the pin to blink and the waiting time.
-With a parallel combinator, tasks are executed seamingly at the same time, i.e.\ their very short small-step reduction steps are interleaved.
+With a parallel combinator, tasks are executed seemingly at the same time, i.e.\ their very short small-step reduction steps are interleaved.
Therefore, blinking three different blinking patterns is as simple as combining the three calls to the \cleaninline{blink} function with their arguments as seen in \cref{lst:blinkthreadmtask}.
% VimTeX: SynIgnore on
declarePin D1 PMOutput \d1->
declarePin D2 PMOutput \d2->
declarePin D3 PMOutput \d3->
- fun \blink=(\(st, pin, wait)->
+ fun \blink = (\(st, pin, wait)->
delay wait
>>|. writeD pin st
>>|. blink (Not st, pin, wait))
\end{lstClean}
% VimTeX: SynIgnore off
-\section{Reading guide}
+\section{Conclusion and reading guide}
This chapter introduced traditional edge device programming and programming edge devices using \gls{MTASK}.
The edge layer of \gls{IOT} systems is powered by microcontrollers.
Microcontrollers have significantly different characteristics to regular computers.
\begin{lstClean}[label={lst:mtask_device},caption={Device communication interface in \gls{MTASK}.}]
:: MTDevice //abstract
:: Channels :== ([MTMessageFro], [MTMessageTo], Bool)
-
class channelSync a :: a (Shared sds Channels) -> Task () | RWShared sds
-
withDevice :: a (MTDevice -> Task b)
-> Task b | iTask b & channelSync, iTask a
\end{lstClean}
\item the upstream \glspl{SDS} are monitored by spawning tasks that watch these \glspl{SDS}, if one is updated, the novel value is sent to the edge device.
\end{enumerate}
-\begin{lstClean}[label={lst:liftmTask_pseudo},caption={Pseudocode implementation for \texttt{liftmTask}.}]
+\begin{lstClean}[float=,label={lst:liftmTask_pseudo},caption={Pseudocode implementation for \texttt{liftmTask}.}]
liftmTask :: (Main (MTask BCInterpret a)) MTDevice -> Task a | iTask a
liftmTask task (MTDevice dev sdsupdates channels)
= freshTaskId dev
\newpage
\section{Home automation}
-\todo[inline]{Meer uitleg over de applicatie? lijst ipv strings voor keuze?}
-This section presents an interactive home automation program (\cref{lst:example_home_automation}) to illustrate the integration of the \gls{MTASK} language and the \gls{ITASK} system.
+This section presents an interactive home automation program (\cref{lst:example_home_automation}) to illustrate the integration of the \gls{MTASK} language and the \gls{ITASK} system.\todo{Meer uitleg over de applicatie? lijst ipv strings voor keuze?}
It consists of a web interface for the user to control which tasks are executed on either one of two connected devices: an \gls{ARDUINO} UNO, connected via a serial port; and an ESP8266 based prototyping board called NodeMCU, connected via \gls{TCP}\slash{}\gls{WIFI}.
\Crefrange{lst:example:spec1}{lst:example:spec2} show the specification for the devices.
The UNO is connected via serial using the UNIX filepath \path{/dev/ttyACM0} and the default serial port settings.
someTask =
sensor1 config1 \sns1->
sensor2 config2 \sns2->
- sds \s1 = initialValue
- In lowerSds \s2 = someiTaskSDS
- In fun \fun1= ( \(a0, a1)->... )
- In fun \fun2= ( \a->... )
+ sds \s1 = initialValue
+ In lowerSds \s2 = someiTaskSDS
+ In fun \fun1 = ( \(a0, a1)->... )
+ In fun \fun2 = ( \a->... )
In { main = mainexpr }
\end{lstClean}
% VimTeX: SynIgnore off
In \gls{CLEAN}, all free variables in a type are implicitly universally quantified.
In order to use the \gls{MTASK} expressions with multiple interpretations, rank-2 polymorphism is required \citep{odersky_putting_1996}.
\Cref{lst:rank2_mtask} shows an example of a function that simulates an \gls{MTASK} expression while showing the pretty printed representation in parallel.
-Providing a type for the \cleaninline{simulateAndPrint} function is mandatory as the compiler cannot infer the type of rank-2 polymorphic functions\citep[\citesection{3.7.4}]{plasmeijer_clean_2021}.
+Providing a type for the \cleaninline{simulateAndPrint} function is mandatory as the compiler cannot infer the type of rank-2 polymorphic functions \citep[\citesection{3.7.4}]{plasmeijer_clean_2021}.
\begin{lstClean}[label={lst:rank2_mtask},caption={Rank-2 polymorphism to allow multiple interpretations.}]
simulateAndPrint :: (A.v: Main (MTask v a) | mtask v) -> Task a | type a
\Cref{lst:example_exprs} shows some examples of expressions in the \gls{MTASK} language.
Since they are only expressions, there is no need for a \cleaninline{Main}.
\cleaninline{e0} defines the literal \num{42}, \cleaninline{e1} calculates the literal \num{42.0} using real numbers and uses a type conversion.
-\cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns $\frac{\text{\cleaninline{e2}}}{2}$ and \cleaninline{e0} otherwise.
+\cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns $\nicefrac{\text{\cleaninline{e2}}}{2}$ and \cleaninline{e0} otherwise.
\begin{lstClean}[label={lst:example_exprs},caption={Example \gls{MTASK} expressions.}]
e0 :: v Int | expr v
It performs a simple approximate equality---admittedly not taking into account all floating point peculiarities.
When calling \cleaninline{approxEqual} in an \gls{MTASK} expression, the resulting code is inlined.
-\begin{lstClean}[label={lst:example_macro},caption={Approximate equality as an example of linguistic reuse in \gls{MTASK}.}]
+\begin{lstClean}[label={lst:example_macro},caption={Approximate equality in \gls{MTASK}.}]
approxEqual :: (v Real) (v Real) (v Real) -> v Bool | expr v
-approxEqual x y eps = x ==. y |. If (x >. y)
- (x -. y <. eps)
- (y -. x <. eps)
+approxEqual x y eps = x ==. y
+ |. If (x >. y)
+ (x -. y <. eps)
+ (y -. x <. eps)
\end{lstClean}
\subsection{Data types}
\end{lstClean}
\subsection{Functions}\label{sec:mtask_functions}
-Adding functions to the language is achieved by one type class to the \gls{DSL}.
-By using \gls{HOAS}, both the function definition and the calls to the function can be controlled by the \gls{DSL} \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
-The \gls{MTASK} language only allows first-order functions and no partial function application.
-To restrict this, a multi-parameter type class is used instead of a type class with one type variable.
+Adding functions to the language is achieved by one type class in the \gls{MTASK} \gls{DSL}.
+By using \gls{HOAS}, both the function definitions and the calls to the functions are controlled by the \gls{DSL} \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
+The \gls{MTASK} language enforces all functions to be first-order and forbids partial function application in order to reduce memory use and code size.
+These restrictions are enforced by using a multi-parameter type class with two parameters instead of a type class with one type variable.
The first parameter represents the shape of the arguments, the second parameter the interpretation.
An instance is provided for each function arity instead of providing an instance for all possible arities to enforce that all functions are first order.
-By using argument tuples to represent the arity of the function, partial function applications are eradicated.
-The definition of the type class and some instances for the pretty printer are as follows:
+By using argument tuples to represent the arity of the function, it is not possible to create partial function applications.
+The definition of the type class and some instances for the pretty printer are shown in \cref{lst:fun_mtask}.
-\begin{lstClean}[caption={Functions in \gls{MTASK}.}]
+\begin{lstClean}[float=,caption={Functions in \gls{MTASK}.},label={lst:fun_mtask}]
class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
-> Main (MTask v u)
\end{lstClean}
Deriving how to define and use functions from the type is quite a challenge even though the resulting syntax is made easier using the infix type \cleaninline{In}.
+Splitting out the function definition for each single arity means that for every function arity and combination of arguments, a separate class constraint is required.
+Many of the often used functions signatures are in the \cleaninline{mtask} class constraint collection.
\Cref{lst:function_examples} show some examples of functions to illustrate the syntax.
-Splitting out the function definition for each single arity means that for every function arity and combination of arguments, a separate class constraint must be created.
-Many of the often used functions are already bundled in the \cleaninline{mtask} class constraint collection.
The \cleaninline{factorial} functions shows a recursive version of the factorial function.
-The \cleaninline{factorialtail} function is a tail-call optimised version of the factorial function.
+The \cleaninline{factorialtail} function is a tail-call optimised version of the above.
It also illustrates a manually added class constraint, as they are required when functions are used that have signatures not present in the \cleaninline{mtask} class collection.
-Zero-arity functions are always called with unit as an argument.
-An illustration of this is seen in the \cleaninline{zeroarity} expression.
-Finally, \cleaninline{swapTuple} shows an example of a tuple being swapped.
+Zero-arity functions are always called with unit as an argument, which is shown in the \cleaninline{zeroarity} function.
+Finally, the \cleaninline{swapTuple} function shows an example of a tuple being swapped using the \cleaninline{tupopen} macro (see \cref{lst:tuple_exprs}).
% VimTeX: SynIgnore on
\begin{lstClean}[label={lst:function_examples},caption={Examples of various functions in \gls{MTASK}.}]
factorial :: Main (v Int) | mtask v
factorial =
- fun \fac=(\i->If (i <. lit 1)
+ fun \fac = (\i->If (i <. lit 1)
(lit 1)
(i *. fac (i -. lit 1)))
In {main = fac (lit 5) }
factorialtail :: Main (v Int) | mtask v & fun (v Int, v Int) v
factorialtail =
- fun \facacc=(\(acc, i)->If (i <. lit 1)
+ fun \facacc = (\(acc, i)->If (i <. lit 1)
acc
(fac (acc *. i, i -. lit 1)))
- In fun \fac=(\i->facacc (lit 1, i))
+ In fun \fac = (\i->facacc (lit 1, i))
In {main = fac (lit 5) }
zeroarity :: Main (v Int) | mtask v
zeroarity =
- fun \fourtytwo=(\()->lit 42)
- In fun \add=(\(x, y)->x +. y)
+ fun \fourtytwo = (\()->lit 42)
+ In fun \add = (\(x, y)->x +. y)
In {main = add (fourtytwo (), lit 9)}
-
+ [+\pagebreak+]
swapTuple :: Main (v (Int, Bool)) | mtask v
swapTuple =
- fun \swap=(tupopen \(x, y)->tupl y x)
+ fun \swap = (tupopen \(x, y)->tupl y x)
In {main = swap (tupl true (lit 42)) }
\end{lstClean}
% VimTeX: SynIgnore off
For the \gls{DHT} sensor there are two basic tasks, \cleaninline{temperature} and \cleaninline{humidity}, that produce a task that yields the observed temperature in \unit{\celcius} or the relative humidity as an unstable value.
Other peripherals have similar interfaces, they are available in \cref{sec:aux_peripherals}.
-\begin{lstClean}[label={lst:dht},caption={The \gls{MTASK} interface for \glspl{DHT} sensors.}]
+\begin{lstClean}[float=,label={lst:dht},caption={The \gls{MTASK} interface for \glspl{DHT} sensors.}]
:: DHT //abstract
:: DHTInfo
= DHT_DHT Pin DHTtype
\begin{itemize}
\item sequential combinators that execute tasks one after the other, possibly using the result of the left-hand side;
\item parallel combinators that execute tasks at the same time, combining the result;
- \item miscellaneous combinators that change the semantics of a task---for example a combinator that repeats the child task.
+ \item and miscellaneous combinators that change the semantics of a task---for example a combinator that repeats the child task.
\end{itemize}
\subsubsection{Sequential}
Every rewrite step, the list of task continuations are tested on the task value.
If one of the predicates matches, the task continues with the result of these continuations.
Several shorthand combinators are derived from the step combinator.
-\cleaninline{>>=.} is a shorthand for the bind operation, if the left-hand side is stable, the right-hand side function is called to produce a new task.
-\cleaninline{>>\|.} is a shorthand for the sequence operation, if the left-hand side is stable, it continues with the right-hand side task.
+The \cleaninline{>>=.} combinator is a shorthand for the bind operation, if the left-hand side is stable, the right-hand side function is called to produce a new task.
+The \cleaninline{>>\|.} combinator is a shorthand for the sequence operation, if the left-hand side is stable, it continues with the right-hand side task.
The \cleaninline{>>~.} and \cleaninline{>>..} combinators are variants of the ones above that ignore the stability and continue on an unstable value as well.
\begin{lstClean}[label={lst:mtask_sequential},caption={Sequential task combinators in \gls{MTASK}.}]
| Always (MTask v u)
\end{lstClean}
-The following listing shows an example of a step in action.
+\Cref{lst:mtask_readpinbin} shows an example task containing a step.
The \cleaninline{readPinBin} function produces an \gls{MTASK} task that classifies the value of an analogue pin into four bins.
It also shows that the nature of embedding allows the host language to be used as a macro language.
The disjunction combinator (\cleaninline{.\|\|.}) combines the results by picking the leftmost, most stable task.
The semantics of both parallel combinators are most easily described using the \gls{CLEAN} functions shown in \cref{lst:semantics_con,lst:semantics_dis}.
-\begin{figure}[ht]
+\begin{figure}
\centering
\begin{subfigure}[t]{.5\textwidth}
\begin{lstClean}[caption={Semantics of the\\conjunction combinator.},label={lst:semantics_con}]
This task read two pins at the same time, returning when one of the pins becomes high.
If the combinator was the \cleaninline{.&&.}, the type would be \cleaninline{MTask v (Bool, Bool)} and the task would only return when both pins are high but not necessarily at the same time.
-\begin{lstClean}[label={lst:mtask_parallel_example},caption={Parallel task combinator example in \gls{MTASK}.}]
+\begin{lstClean}[float=,label={lst:mtask_parallel_example},caption={Parallel task combinator example in \gls{MTASK}.}]
task :: MTask v Bool
task =
declarePin D0 PMInput \d0->
declarePin D1 PMInput \d1->
- let monitor pin = readD pin >>*. [IfValue id rtrn]
+ fun \monitor = (\pin->readD pin >>*. [IfValue id rtrn])
In {main = monitor d0 .||. monitor d1}
\end{lstClean}
It runs the pretty printer and returns a list of strings containing the pretty printed result.
The pretty printing function does the best it can but obviously cannot reproduce layout, curried functions, and variable names.
This shortcoming is illustrated by printing a blink task that contains a function and currying in \cref{lst:showexample}.
+The output of this action would be \cleaninline{fun f0 a1 = writeD(D13, a1) >>= \\a2.(delay 1000) >>\| (f0 (Not a1)) in (f0 True)}
\begin{lstClean}[caption={The entry point for the pretty printing interpretation.},label={lst:showmain}]
:: Show a // from the mTask pretty printing library
fun \blink=(\state->
writeD d13 state >>|. delay (lit 500) >>=. blink o Not
) In {main = blink true}
-
-// output when printing:
-// fun f0 a1 = writeD(D13, a1) >>= \a2.(delay 1000)
-// >>| (f0 (Not a1)) in (f0 True)
\end{lstClean}
\subsection{Simulator}