Abstract
The Internet of Things (IoT) is growing fast. In 2018, there was approximately one connected device per person on earth and the number has been growing ever since. The devices interact with the environment via different modalities at the same time using sensors and actuators making the programs parallel. Yet, writing this type of programs is difficult because the devices have little computation power and memory, the platforms are heterogeneous and the languages are low level. Task Oriented Programming (TOP) is a declarative programming language paradigm that is used to express coordination of work, collaboration of users and systems, the distribution of shared data and the human-computer interaction. The mTask language is a specialized, yet full-fledged, multi-backend TOP language for IoT devices. With the bytecode interpretation backend and the integration with iTask, tasks can be executed on the device dynamically. This means that—according to the current state of affairs—tasks can be tailor-made at run time, compiled to device-agnostic bytecode and shipped to the device for interpretation. Tasks sent to the device are fully integrated in iTask to allow every form of interaction with the tasks such as observation of the task value and interaction with Shared Data Sources (SDSs). The entire IoT application—both server and devices—are programmed in a single language, albeit using two embedded Domain Specific Languages (EDSLs).
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Notes
- 1.
Gartner (August 2019).
- 2.
Atmel, the producer of AVR microprocessors, specifies the flash memory of the MCU in the Arduino UNO to about 10,000 cycles. This specification is a minimal specification and most likely the memory will be able to sustain many more writes. However, even if the memory can sustain ten times the amount, it is still a short time. .
- 3.
- 4.
- 5.
The exact question is left as an exercise to the reader but the answer is 42 [2].
- 6.
While a bit out of scope, it deserves mention that for SN, FRP and stream based approaches are popular as well [46].
- 7.
Instructions from https://hmgaudecker.github.io/econ-python-environment/paths.html.
- 8.
References
Achten, P.: Clean for Haskell98 Programmers (2007)
Adams, D.: The Hitchhiker’s Guide to the Galaxy Omnibus: A Trilogy in Four Parts, vol. 6. Pan Macmillan (2017)
Alimarine, A.: Generic Functional Programming. Ph.D., Radboud University, Nijmegen (2005)
Amazonas Cabral De Andrade, M.: Developing real life, task oriented applications for the internet of things. Master’s thesis, Radboud University, Nijmegen (2018)
Amsden, E.: A survey of functional reactive programming. Technical report (2011)
Baccelli, E., et al.: Reprogramming low-end IoT devices from the cloud. In: 2018 3rd Cloudification of the Internet of Things (CIoT), pp. 1–6. IEEE (2018)
Baccelli, E., Doerr, J., Kikuchi, S., Padilla, F., Schleiser, K., Thomas, I.: Scripting over-the-air: towards containers on low-end devices in the internet of things. In: IEEE PerCom 2018 (2018)
Bolderheij, F., Jansen, J.M., Kool, A.A., Stutterheim, J.: A mission-driven C2 framework for enabling heterogeneous collaboration. In: Monsuur, H., Jansen, J.M., Marchal, F.J. (eds.) NL ARMS Netherlands Annual Review of Military Studies 2018. NA, pp. 107–130. T.M.C. Asser Press, The Hague (2018). https://doi.org/10.1007/978-94-6265-246-0_6
Brus, T.H., van Eekelen, M.C.J.D., van Leer, M.O., Plasmeijer, M.J.: Clean — a language for functional graph rewriting. In: Kahn, G. (ed.) FPCA 1987. LNCS, vol. 274, pp. 364–384. Springer, Heidelberg (1987). https://doi.org/10.1007/3-540-18317-5_20
Carette, J., Kiselyov, O., Shan, C.C.: Finally tagless, partially evaluated: tagless staged interpreters for simpler typed languages. J. Funct. Program. 19(05), 509 (2009). https://doi.org/10.1017/S0956796809007205
Cheney, J., Hinze, R.: First-class phantom types. Technical report, Cornell University (2003)
Da Xu, L., He, W., Li, S.: Internet of things in industries: a survey. IEEE Trans. Ind. Inform. 10(4), 2233–2243 (2014)
Domoszlai, L., Lijnse, B., Plasmeijer, R.: Parametric lenses: change notification for bidirectional lenses. In: Proceedings of the 26nd 2014 International Symposium on Implementation and Application of Functional Languages, p. 9. ACM (2014)
Dubé, D.: BIT: a very compact Scheme system for embedded applications. In: Proceedings of the Fourth Workshop on Scheme and Functional Programming (2000)
Elliott, C., Hudak, P.: Functional reactive animation. In: ACM SIGPLAN Notices, vol. 32, pp. 263–273. ACM (1997)
Feeley, M., Dubé, D.: PICBIT: a scheme system for the PIC microcontroller. In: Proceedings of the Fourth Workshop on Scheme and Functional Programming, pp. 7–15. Citeseer (2003)
Feijs, L.: Multi-tasking and Arduino: why and how? In: Chen, L.L., et al. (eds.) Design and Semantics of form and Movement. 8th International Conference on Design and Semantics of Form and Movement (DeSForM 2013), Wuxi, China, pp. 119–127 (2013)
Grebe, M., Gill, A.: Haskino: a remote monad for programming the arduino. In: Gavanelli, M., Reppy, J. (eds.) PADL 2016. LNCS, vol. 9585, pp. 153–168. Springer, Cham (2016). https://doi.org/10.1007/978-3-319-28228-2_10
Grebe, M., Gill, A.: Threading the Arduino with Haskell. In: Van Horn, D., Hughes, J. (eds.) TFP 2016. LNCS, vol. 10447, pp. 135–154. Springer, Cham (2019). https://doi.org/10.1007/978-3-030-14805-8_8
Haenisch, T.: A case study on using functional programming for internet of things applications. Athens J. Technol. Eng. 3(1), 29–38 (2016)
Helbling, C., Guyer, S.Z.: Juniper: a functional reactive programming language for the Arduino. In: Proceedings of the 4th International Workshop on Functional Art, Music, Modelling, and Design, pp. 8–16. ACM (2016)
Hess, J.: Arduino-copilot: arduino programming in haskell using the Copilot stream DSL (2020). http://hackage.haskell.org/package/arduino-copilot
Hickey, P.C., Pike, L., Elliott, T., Bielman, J., Launchbury, J.: Building embedded systems with embedded DSLs. In: ACM SIGPLAN Notices, vol. 49, pp. 3–9. ACM Press (2014). https://doi.org/10.1145/2628136.2628146
Jansen, J.M., Lijnse, B., Plasmeijer, R.: Towards dynamic workflows for crisis management (2010)
Johnson-Davies, D.: Lisp for microcontrollers (2020). https://ulisp.com
Koopman, P., Lubbers, M., Plasmeijer, R.: A task-based DSL for microcomputers. In: Proceedings of the Real World Domain Specific Languages Workshop 2018 on - RWDSL 2018, Vienna, Austria, pp. 1–11. ACM Press (2018). https://doi.org/10.1145/3183895.3183902
Lijnse, B., Jansen, J.M., Nanne, R., Plasmeijer, R.: Capturing the netherlands coast guard’s sar workflow with itasks (2011)
Lijnse, B., Jansen, J.M., Plasmeijer, R., others: Incidone: a task-oriented incident coordination tool. In: Proceedings of the 9th International Conference on Information Systems for Crisis Response and Management, ISCRAM, vol. 12 (2012)
Lijnse, B., Plasmeijer, R.: iTasks 2: iTasks for end-users. In: Morazán, M.T., Scholz, S.-B. (eds.) IFL 2009. LNCS, vol. 6041, pp. 36–54. Springer, Heidelberg (2010). https://doi.org/10.1007/978-3-642-16478-1_3
Lubbers, M., Koopman, P., Plasmeijer, R.: Multitasking on microcontrollers using task oriented programming. In: 2019 42nd International Convention on Information and Communication Technology, Electronics and Microelectronics (MIPRO), Opatija, Croatia, pp. 1587–1592 (2019). https://doi.org/10.23919/MIPRO.2019.8756711
Lubbers, M.: Task oriented programming and the internet of things. Master’s thesis, Radboud University, Nijmegen (2017)
Lubbers, M., Koopman, P., Plasmeijer, R.: Task oriented programming and the internet of things. In: Proceedings of the 30th Symposium on the Implementation and Application of Functional Programming Languages, Lowell, MA, p. 12. ACM (2018). https://doi.org/10.1145/3310232.3310239
Lubbers, M., Koopman, P., Plasmeijer, R.: Interpreting task oriented programs on tiny computers. In: Proceedings of the 31st Symposium on Implementation and Application of Functional Languages, IFL 2019, Singapore, Singapore. Association for Computing Machinery, New York (2019). https://doi.org/10.1145/3412932.3412936
Michels, S., Plasmeijer, R.: Uniform data sources in a functional language, p. 16. Unpublished manuscript (2012)
Piers, J.: Task-oriented programming for developing non-distributed interruptible embedded systems. Master’s thesis, Radboud University, Nijmegen (2016)
Plasmeijer, R., Achten, P.: A conference management system based on the iData Toolkit. In: Horváth, Z., Zsók, V., Butterfield, A. (eds.) IFL 2006. LNCS, vol. 4449, pp. 108–125. Springer, Heidelberg (2007). https://doi.org/10.1007/978-3-540-74130-5_7
Plasmeijer, R., Achten, P., Koopman, P.: iTasks: executable specifications of interactive work flow systems for the web. ACM SIGPLAN Not. 42(9), 141–152 (2007)
Koopman, P., Plasmeijer, R.: A shallow embedded type safe extendable DSL for the Arduino. In: Serrano, M., Hage, J. (eds.) TFP 2015. LNCS, vol. 9547, pp. 104–123. Springer, Cham (2016). https://doi.org/10.1007/978-3-319-39110-6_6
Plasmeijer, R., Lijnse, B., Michels, S., Achten, P., Koopman, P.: Task-oriented programming in a pure functional language. In: Proceedings of the 14th Symposium on Principles and Practice of Declarative Programming, pp. 195–206. ACM (2012)
Sant’Anna, F., Rodriguez, N., Ierusalimschy, R., Landsiedel, O., Tsigas, P.: Safe system-level concurrency on resource-constrained nodes. In: Proceedings of the 11th ACM Conference on Embedded Networked Sensor Systems, p. 11. ACM (2013)
Sawada, K., Watanabe, T.: Emfrp: a functional reactive programming language for small-scale embedded systems. In: Companion Proceedings of the 15th International Conference on Modularity, pp. 36–44. ACM (2016)
Serrano, A.: Type error customization for embedded domain-specific languages. Ph.D. thesis, Utrecht University (2018)
St-Amour, V., Feeley, M.: PICOBIT: a compact scheme system for microcontrollers. In: Morazán, M.T., Scholz, S.-B. (eds.) IFL 2009. LNCS, vol. 6041, pp. 1–17. Springer, Heidelberg (2010). https://doi.org/10.1007/978-3-642-16478-1_1
Steiner, H.C.: Firmata: towards making microcontrollers act like extensions of the computer. In: NIME, pp. 125–130 (2009)
Stutterheim, J., Achten, P., Plasmeijer, R.: Maintaining separation of concerns through task oriented software development. In: Wang, M., Owens, S. (eds.) TFP 2017. LNCS, vol. 10788, pp. 19–38. Springer, Cham (2018). https://doi.org/10.1007/978-3-319-89719-6_2
Sugihara, R., Gupta, R.K.: Programming models for sensor networks: a survey. ACM Trans. Sensor Netw. 4(2), 1–29 (2008). https://doi.org/10.1145/1340771.1340774
Troyer, de, C., Nicolay, J., Meuter, de, W.: Building IoT systems using distributed first-class reactive programming. In: 2018 IEEE International Conference on Cloud Computing Technology and Science (CloudCom), pp. 185–192 (2018). https://doi.org/10.1109/CloudCom2018.2018.00045
van der Heijden, M., Lijnse, B., Lucas, P.J.F., Heijdra, Y.F., Schermer, T.R.J.: Managing COPD exacerbations with telemedicine. In: Peleg, M., Lavrač, N., Combi, C. (eds.) AIME 2011. LNCS (LNAI), vol. 6747, pp. 169–178. Springer, Heidelberg (2011). https://doi.org/10.1007/978-3-642-22218-4_21
Wand, M.: Continuation-based multiprocessing. In: Proceedings of the 1980 ACM Conference on LISP and Functional Programming - LFP 1980, Stanford University, California, United States, pp. 19–28. ACM Press (1980). https://doi.org/10.1145/800087.802786
Acknowledgements
This paper constitutes the adapted lecture notes for the hands-on course presented at the Central European Functional Programming School (CEFP) in Budapest between 17 and 21 June 2019. This research is partly funded by the Royal Netherlands Navy. Furthermore, we would like to thank the reviewers for their valuable comments.
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Appendices
A Embedded Domain Specific Language Techniques
An EDSL is a language embedded in a host language created for a specific domain [23]. EDSLs can have one or more backends or views. Commonly used views are pretty printing, compiling, simulating, verifying and proving the program. There are several techniques available for creating EDSLs. They all have their own advantages and disadvantages in terms of extendability, type safety and view support. In the following subsections each of the main techniques are briefly explained. An example expression DSL is used as a running example.
1.1 A.1 Deep Embedding
A deeply EDSL is a language represented as data in the host language. Views are functions that transform something to the datatype or the other way around. Definition 20 shows an example implementation for the expression DSL.
Deep embedding has the advantage that it is easy to build and views are easy to add. On the downside, the expressions created with this language are not necessarily type-safe. In the given language it is possible to create an expression such as Plus (LitI 4) (LitB True) that adds a boolean to an integer. Extending the Algebraic Datatype (ADT) is easy and convenient but extending the views accordingly is tedious since it has to be done individually for all views.
The first downside of this type of EDSL can be overcome by using Generalized ADTs (GADTs) [11]. Example 21 shows the same language, but type-safe with a GADT. GADTs are not supported in the current version of Clean and therefore the syntax is hypothetical. However, it has been shown that GADTs can be simulated using bimaps or projection pairs [11]. Unfortunately the lack of extendability remains a problem. If a language construct is added, no compile time guarantee can be given that all views support it.
1.2 A.2 Shallow Embedding
In a shallowly EDSL all language constructs are expressed as functions in the host language. An evaluator view for the example language then can be implemented as the code shown in Definition 22. Note that much of the internals of the language can be hidden using monads.
The advantage of shallowly embedding a language in a host language is its extendability. It is very easy to add functionality because the compile time checks of the host language guarantee whether or not the functionality is available when used. Moreover, the language is type safe as it is directly typed in the host language, i.e. Lit True +. Lit 4 is rejected.
The downside of this method is extending the language with views. It is nearly impossible to add views to a shallowly embedded language. The only way of achieving this is by reimplementing all functions so that they run all backends at the same time. This will mean that every component will have to implement all views rendering it slow for multiple views and complex to implement.
B iTask reference
This appendix gives a brief overview of iTask. It is by far extensive but should cover all iTask constructions required for the exercises. Some examples from [45] can be found in Sect. B.6.
1.1 B.1 Types
The class collection iTask is used throughout the library to make sure the types used have all the required machinery for iTask. This class collection contains only generic functions that can automatically be derived for any first order user defined type. Example 23 shows how to derive this class.
1.2 B.2 Editors
The most common basic tasks are editors for entering, viewing or update information. For the three basic editors there are three corresponding functions to create tasks as seen in Definition 23.
The first argument of the function is something implementing toPrompt. There are toPrompt instances for at least String—for a description, (String, String)—for a title and a description and ()—for no description.
The second argument is a list of options for modifying the editor behaviour. This list is either empty or contains exactly one item. The types for the options are shown in Definition 24. Simple lenses are created using the *As constructor. If an entirely different editor must be used, the *Using constructors can be used.
Example 24 shows an example of such an editor using a lens. The user enters a temperature in degrees Celsius and the editor automatically converts the result to a temperature in Fahrenheit which is in turn the observed task value.
1.3 B.3 Task Combinators
There are two flavours of task combinators, namely parallel and sequential that are all specializations of their Swiss-army knife combinator step and parallel respectively.
Parallel Combinators. The two main parallel combinators are the conjunction and disjunction combinators shown in Definition 25.
The - &&- has semantics similar to the mTask . &&. combinator. The -||- has the same semantics as the mTask .||. combinator. The -|| and ||- executes both tasks in parallel but only looks at the value of the left task or the right task respectively.
Example 25 shows an example of a task that, using the disjunction combinator, asks the user for a temperature either in degrees Celsius or Fahrenheit using the task from Example 24. Whichever editor the user edits last, will be the observable task value.
Sequential Combinators. All sequential combinators are derived from the \(\texttt {>>*}\) combinator as shown in Definition 26. With this combinator, the task value of the left-hand side can be observed and execution continues with the right-hand side if one of the continuations yields a Just (Task b). The listing also shows many utility functions for defining task steps.
Example 26 shows an example of the step combinator that forces the user to enter a number between 0 and 10. If the user enters a different value, the continue button will remain disabled.
Derived from the \(\texttt {>>*}\) combinator are all other sequential combinators such as the ones listed in Definition 27 with their respective documentation.
1.4 B.4 Shared Data Sources
Data can be observer via task values but for unrelated tasks to share data, SDSs are used. There is an publish subscribe system powering the SDS system that makes sure tasks are only rewritten when activity has taken place in the SDS. There are many types of SDSs such as lenses, sources and combinators. As long as they implement the RWShared class collection, you can use them as an SDS. Definition 28 shows two methods for creating an SDS, they both yield a SimpleSDSLens but they can be used by any task using an SDS.
With the sharedStore function, a named SDS can be created that acts as a well-typed global variable. withShared is used to create an anonymous local SDS.
There are four major operations that can be done on SDSs that are all atomic (see Definition 29). get fetches the value from the SDS and yields it as a stable value. set writes the given value to the SDS and yields it as a stable value. upd applies an update function to the SDS and returns the written value as a stable value. watch continuously emits the value of the SDS as an unstable task value. The implementation uses a publish subscribe system to evaluate the watch task only when the value of the SDS changes.
For all editors, there are shared variants available as shown in Definition 27. This allows a user to interact with the SDS.
1.5 B.5 Extra Task Combinators
Not all workflow patterns can be described using only the derived combinators. Therefore, some other task combinators have been invented that are not truly sequential nor truly parallel. Definition 31 shows some combinators that might be useful in the exercises.
1.6 B.6 Examples
Some workflow task patterns can easily be created using the builtin combinator as shown in Examples 28.
C How to Install
This section will give detailed instructions on how to install mTask on your system. The distribution used also includes the example skeletons.
1.1 C.1 Fetch the CEFP distribution
Download the CEFP version of mTask distribution for your operating system as given in Table 2 and decompress the archive. The archives is all you need since it contains a complete clean distribution. The windows version contains an IDE and Clean Project Manager (cpm). Mac and Linux only have a project manager called cpm.
1.2 C.2 Setup
Linux. Assuming you uncompressed the archive in , run the following commands in a terminal.
Windows. You do not need to setup anything on windows. However, if you want to use cpm as well, you need to add the to your %PATH%Footnote 7.
MacOS. Assuming you uncompressed the archive in , run the following commands in a terminal.
1.3 C.3 Compile the Test Program
Note that the first time compiling everything can take a while and will consume quite some memory.
Windows. Assuming you uncompressed the archive in . Connect a device or start the local TCP client by executing
IDE
-
Open the IDE by starting .
-
Click on or press ond open .
-
Click on or press .
cpm Enter the following commands in a command prompt or PowerShell session:
Linux & MacOS. Assuming you uncompressed the archive in . Connect a device or start the local TCP client by executing . In a terminal enter the following commands:
1.4 C.4 Setup the Microcontroller Unit
For setting up the RTS for the MCU, the reader is kindly referred to hereFootnote 8.
D Solutions
Rights and permissions
Copyright information
© 2023 The Author(s), under exclusive license to Springer Nature Switzerland AG
About this paper
Cite this paper
Lubbers, M., Koopman, P., Plasmeijer, R. (2023). Writing Internet of Things Applications with Task Oriented Programming. In: Porkoláb, Z., Zsók, V. (eds) Composability, Comprehensibility and Correctness of Working Software. CEFP 2019. Lecture Notes in Computer Science, vol 11950. Springer, Cham. https://doi.org/10.1007/978-3-031-42833-3_1
Download citation
DOI: https://doi.org/10.1007/978-3-031-42833-3_1
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-031-42832-6
Online ISBN: 978-3-031-42833-3
eBook Packages: Computer ScienceComputer Science (R0)