23 research outputs found

    Towards a Decoupled Context-Oriented Programming Language for the Internet of Things

    Get PDF
    Easily programming behaviors is one major issue of a large and reconfigurable deployment in the Internet of Things. Such kind of devices often requires to externalize part of their behavior such as the sensing, the data aggregation or the code offloading. Most existing context-oriented programming languages integrate in the same class or close layers the whole behavior. We propose to abstract and separate the context tracking from the decision process, and to use event-based handlers to interconnect them. We keep a very easy declarative and non-layered programming model. We illustrate by defining an extension to Golo-a JVM-based dynamic language

    Versatile event correlation with algebraic effects

    Get PDF
    We present the first language design to uniformly express variants of n -way joins over asynchronous event streams from different domains, e.g., stream-relational algebra, event processing, reactive and concurrent programming. We model asynchronous reactive programs and joins in direct style, on top of algebraic effects and handlers. Effect handlers act as modular interpreters of event notifications, enabling fine-grained control abstractions and customizable event matching. Join variants can be considered as cartesian product computations with ”degenerate” control flow, such that unnecessary tuples are not materialized a priori. Based on this computational interpretation, we decompose joins into a generic, naive enumeration procedure of the cartesian product, plus variant-specific extensions, represented in terms of user-supplied effect handlers. Our microbenchmarks validate that this extensible design avoids needless materialization. Alongside a formal semantics for joining and prototypes in Koka and multicore OCaml, we contribute a systematic comparison of the covered domains and features. ERC, Advanced Grant No. 321217 ERC, Consolidator Grant No. 617805 DFG, SFB 1053 DFG, SA 2918/2-

    An Expressive Stateful Aspect Language

    Get PDF
    Abstract Stateful aspects can react to a program execution; they support modular implementations of several crosscutting concerns like error detection, security, event handling, and debugging. However, most proposed stateful aspect languages have specifically been tailored to address a particular concern. Indeed, most of these languages differ in their pattern languages and semantics. As a consequence, developers need to tweak aspect definitions in contortive ways or create new specialized stateful aspect languages altogether if their specific needs are not supported. In this paper, we describe ESA, an expressive stateful aspect language, in which the pattern language is Turing-complete and patterns themselves are reusable, composable first-class values. In addition, the core semantic elements of every aspect in ESA is open to customization. We describe ESA in a typed functional language. We use this description to develop a concrete and practical implementation of ESA for JavaScript. With this implementation, we illustrate the expressiveness of ESA in action with examples of diverse scenarios and expressing semantics of existing stateful aspect languages

    Programming with implicit flows

    Get PDF
    Modern software differs significantly from traditional computer applications that mostly process reasonably small amounts of static input data-sets in batch mode. Modern software increasingly processes massive amounts of data, whereby it is also often the case that new input data is produced and/or existing data is modified on the fly. Consequently, programming models that facilitate the development of such software are emerging. What characterizes them is that data, respectively changes thereof, implicitly flow through computation modules. The software engineer declaratively defines computations as compositions of other computations without explicitly modeling how data should flow along dependency relations between data producer and data consumer modules, letting the runtime to automatically manage and optimize data flows. Keywords: Reactive programming, event, stream, big data, data-flow We have come a long way since the early computer systems which were painstakingly fed problem data-sets via punch cards. Computer systems have become much more convenient to interact with and are able to process much larger data-sets, which are kept in large-scale storage systems. However, computer systems are also much more commonly involved in processing of data that is produced or modified in an online fashion, as the program is executing, sometimes in a perpetual manner. This is particularly the case in applications which are specifically developed to react to real-world happenings such as temperature changes or other environmental cues captured through sensors. The last decade has thus seen the advent of abstractions and paradigms that support the development of reactive software. Central to such approaches is the concept of event which captures dynamic occurrences that trigger computations. Over the years, several steps have been made in this direction, including language-level support for events, continuous time-changing values (a.k.a. signals or behaviors), constraints, asynchronous execution and futures. The ever-increasing complexity of reactive applications has recently raised new interest around these abstractions. The new paradigm of reactive programming focuses on a more holistic view that demands for seamless integration of existing solutions, including constraints resolution to enforce functional dependencies, automatic updates of dependent values, and interoperability among different reactive abstractions such as signals and event streams. The goal is to raise the abstraction level: Rather than explicitly reifying events in the software, changes to values of variables are detected and propagated through programs by re-computing the values of all dependent variables implicitly, i.e., by the language runtime. Interestingly, a similar trend can be observed in recent big data analysis software. Not too long ago, such programs were typically perceived as resembling complex queries applied to very large yet static data-sets. A host of programming languages and models have been proposed for such programs. They mostly mix imperative and declarative traits to clearly expose the order of a non-cyclic computation network, and are centered on some form of data-structures conceptualizing the current state of computation. Despite improvements in running time of such analysis programs often due to parallel execution over powerful computation environments, their execution can still take sufficiently long to make repeated complete executions of the same program upon additions or changes to the underlying big data-sets prohibitively expensive. Consequently, recent improvements consist in enabling incremental computations, i.e., re-executing only those parts of queries that become invalid or incomplete by changes to analyzed data-sets. While reactive and big data analysis applications have little in common at first glance, we observe a shared trend in the respective programming models: they strive to capture what the computation ought to do, but not when (and how) it shall do so, as the data which is subject to the computation changes over time (thus we speak of "data-flows"). It is the execution engines and language runtimes that increasingly carry the burden of determining which parts of computations are affected by which fluctuations in the processed data. As it is unlikely that runtime systems can determine these things entirely on their own -at least in an efficient manner -or that such transparency would even serve the programmer, new abstractions are needed to capture such implicit flows in addition to underlying runtime support. In the following, we first overview the nature and origins of reactive programming and big data analysis and implicit flows 1 therein. Next, we briefly touch on the state of the art and open challenges towards a unified approach to programming with implicit flows. Unification makes sense not only because of the shared trend towards implicit flows. More importantly it helps coping with the complexity of software that increasingly combines features from both families of applications. Events and Reactive Programming Events are a common way for programmers to reason about significant conditions in the environment and in the execution of a program. Dedicated abstractions for events have been supported by some mainstream languages for a long time. For example, in C#, events can be defined as class attributes beside methods and fields and belong to a class' interface. Over the last few years, researchers have proposed increasingly sophisticated event models (cf. Box "Avanced programming with events"). The integration into the object-oriented (OO) programming model has been enhanced to extend OO concepts like inheritance to events and event handling. Early approaches like Java P S [2] implemented events as specific objects. In EScala [11] events are first-class entities. As in C#, they are object attributes just like methods and fields; their definition is subject to polymorphic access and late binding. Our investigations Events in isolation improve little over the observer design pattern. The difference becomes crucial when expressive operators for event combination are available to correlate events to define new (complex) events that capture high-level situations of interest. Advanced systems support operators to combine events with increasing levels of expressiveness. For example, the e 1 ||e 2 expression in EScala returns an event that fires when either e 1 or e 2 fires. Full-fledged embeddings of complex event processing like EventJava [3], or stream processing languages like SPL [5], support complex queries over event streams including time windows and joins. In parallel to the development of richer event models, other researchers focused on more inherent data-flow and changedriven solutions for reactive applications. These approaches have old roots. For example, the Garnet and Amulet graphical toolkits The fundamental concept in reactive languages is that programmers do not directly handle the control flow but the execution is driven by the implicit flow of data and the need to update values. Concretely, programmers specify constraints that express functional dependencies among values in the application, and the language runtime enforces these constraints without any further effort from the programmer. More recently, these approaches have inspired many embeddings of DSLs and functional constraints in existing (imperative) programming languages. The advantage of this solution is that programmers specify a functional dependency in an intuitive, declarative way. As a consequence, reactions are directly expressed, do not need to be inferred from the control flow, and can be easily composed. In practice, (continuous) time-changing values, a.k.a. signals, are not enough. The need for events (i.e., discrete timechanging values) is explained by two observations. (a) Events come from external phenomena that are inherently discrete, such as an interrupt or new data from a sensor. (b) Events are better suited for modeling certain behaviors: in principle a mouse click can be modeled as a boolean continuous time-changing value that switches to true when the mouse is clicked, but most programmers would rather think of a mouse click as an event. For this reason, existing reactive languages provide both signals and events. Reactive programming is an emerging trend and identifying the boundaries of this field is hard. However, the following principles seem valid in general. • Declarative style. Reactive behavior is defined in a direct, convenient, declarative style instead of encoding it in design patterns or through imperative updates of program state. Reactions are directly expressed and do not need to be encoded into the control flow of the program. • Composition. Abstractions allow for composition of more complex reactions. Traditional OO applications express reactions in callbacks that are executed when an observable changes. However, callbacks typically perform side effects to modify the state of the application but do not return a value. As a result, they are hard to combine. Instead, events can be combined through combinators, and signals can be combined directly into more complex reactive expressions. • Automation. In AOP, advices are triggered at points in the execution of the program (e.g., the end of a method call) that are referred to as join points. Join points can be seen as events that occur during the execution and treated uniformly with other events. For example, EScala before(method) and after(method) events are triggered before and after the execution of methods.Also, in event-based languages that integrate AOP features, programmers can refer to all events of a certain type, a feature that resembles AOP quantification. As an example of an expressive event system, we show a slice of a drawing application in EScala

    An Overview of Language Support for Modular Event-driven Programming

    Get PDF
    Nowadays, event processing is becoming the backbone of many applications. Therefore, it is necessary to provide suitable abstractions to properly modularize the concerns that appear in event-driven applications. We identify four categories of languages that support event-driven programming, and identify their shortcomings in achieving modularity in the implementation of applications. We propose gummy modules and their implementation in the GummyJ language as a solution. Gummy modules have well-defined event-based interfaces, and can have a primitive or a composite structure. Composite gummy modules are means to group a set of correlated event processing concerns and restrict the visibility of events among them. We provide an example usage of gummy modules, and discuss their event processing semantics
    corecore