17 research outputs found

    Towards Language-Oriented Modeling

    Get PDF
    In this habilitation à diriger des recherches (HDR), I review a decade of research work in the fields of Model-Driven Engineering (MDE) and Software Language Engineering (SLE). I propose contributions to support a language-oriented modeling, with the particular focus on enabling early validation & verification (V&V) of software-intensive systems. I first present foundational concepts and engineering facilities which help to capture the core domain knowledge into the various heterogeneous concerns of DSMLs (aka. metamodeling in the small), with a particular focus on executable DSMLs to automate the development of dynamic V&V tools. Then, I propose structural and behavioral DSML interfaces, and associated composition operators to reuse and integrate multiple DSMLs (aka. metamodeling in the large).In these research activities I explore various breakthroughs in terms of modularity and reusability of DSMLs. I also propose an original approach which bridges the gap between the concurrency theory and the algorithm theory, to integrate a formal concurrency model into the execution semantics of DSMLs. All the contributions have been implemented in software platforms — the language workbench Melange and the GEMOC studio – and experienced in real-world case studies to assess their validity. In this context, I also founded the GEMOC initiative, an attempt to federate the community on the grand challenge of the globalization of modeling languages

    Language Support for Distributed Functional Programming

    Get PDF
    Software development has taken a fundamental turn. Software today has gone from simple, closed programs running on a single machine, to massively open programs, patching together user experiences byway of responses received via hundreds of network requests spanning multiple machines. At the same time, as data continues to stockpile, systems for big data analytics are on the rise. Yet despite this trend towards distributing computation, issues at the level of the language and runtime abound. Serialization is still a costly runtime affair, crashing running systems and confounding developers. Function closures are being added to APIs for big data processing for use by end-users without reliably being able to transmit them over the network. And much of the frameworks developed for handling multiple concurrent requests byway of asynchronous programming facilities rely on blocking threads, causing serious scalability issues. This thesis describes a number of extensions and libraries for the Scala programming language that aim to address these issues and to provide a more reliable foundation on which to build distributed systems. This thesis presents a new approach to serialization called pickling based on the idea of generating and composing functional pickler combinators statically. The approach shifts the burden of serialization to compile time as much as possible, enabling users to catch serialization errors at compile time rather than at runtime. Further, by virtue of serialization code being generated at compile time, our framework is shown to be significantly more performant than other state-of-the-art serialization frameworks. We also generalize our technique for generating serialization code to generic functions other than pickling. Second, in light of the trend of distributed data-parallel frameworks being designed around functional patterns where closures are transmitted across cluster nodes to large-scale persistent datasets, this thesis introduces a new closure-like abstraction and type system, called spores, that can guarantee closures to be serializable, thread-safe, or even have custom user-defined properties. Crucially, our system is based on the principle of encoding type information corresponding to captured variables in the type of a spore. We prove our type system sound, implement our approach for Scala, evaluate its practicality through a small empirical study, and show the power of these guarantees through a case analysis of real-world distributed and concurrent frameworks that this safe foundation for closures facilitates. Finally, we bring together the above building blocks, pickling and spores, to form the basis of a new programming model called function-passing. Function-passing is based on the idea of a distributed persistent data structure which stores in its nodes transformations to data rather than the distributed data itself, simplifying fault recovery by design. Lazy evaluation is also central to our model; by incorporating laziness into our design only at the point of initiating network communication, our model remains easy to reason about while remaining efficient in time and memory. We formalize our programming model in the form of a small-step operational semantics which includes a precise specification of the semantics of functional fault recovery, and we provide an open-source implementation of our model in and for Scala

    Compilation and Code Optimization for Data Analytics

    Get PDF
    The trade-offs between the use of modern high-level and low-level programming languages in constructing complex software artifacts are well known. High-level languages allow for greater programmer productivity: abstraction and genericity allow for the same functionality to be implemented with significantly less code compared to low-level languages. Modularity, object-orientation, functional programming, and powerful type systems allow programmers not only to create clean abstractions and protect them from leaking, but also to define code units that are reusable and easily composable, and software architectures that are adaptable and extensible. The abstraction, succinctness, and modularity of high-level code help to avoid software bugs and facilitate debugging and maintenance. The use of high-level languages comes at a performance cost: increased indirection due to abstraction, virtualization, and interpretation, and superfluous work, particularly in the form of tempory memory allocation and deallocation to support objects and encapsulation. As a result of this, the cost of high-level languages for performance-critical systems may seem prohibitive. The vision of abstraction without regret argues that it is possible to use high-level languages for building performance-critical systems that allow for both productivity and high performance, instead of trading off the former for the latter. In this thesis, we realize this vision for building different types of data analytics systems. Our means of achieving this is by employing compilation. The goal is to compile away expensive language features -- to compile high-level code down to efficient low-level code

    Compilation and Code Optimization for Data Analytics

    Get PDF
    The trade-offs between the use of modern high-level and low-level programming languages in constructing complex software artifacts are well known. High-level languages allow for greater programmer productivity: abstraction and genericity allow for the same functionality to be implemented with significantly less code compared to low-level languages. Modularity, object-orientation, functional programming, and powerful type systems allow programmers not only to create clean abstractions and protect them from leaking, but also to define code units that are reusable and easily composable, and software architectures that are adaptable and extensible. The abstraction, succinctness, and modularity of high-level code help to avoid software bugs and facilitate debugging and maintenance. The use of high-level languages comes at a performance cost: increased indirection due to abstraction, virtualization, and interpretation, and superfluous work, particularly in the form of tempory memory allocation and deallocation to support objects and encapsulation. As a result of this, the cost of high-level languages for performance-critical systems may seem prohibitive. The vision of abstraction without regret argues that it is possible to use high-level languages for building performance-critical systems that allow for both productivity and high performance, instead of trading off the former for the latter. In this thesis, we realize this vision for building different types of data analytics systems. Our means of achieving this is by employing compilation. The goal is to compile away expensive language features -- to compile high-level code down to efficient low-level code

    Object-Centric Reflection: Unifying Reflection and Bringing It Back to Objects

    Get PDF
    Reflective applications are able to query and manipulate the structure and behavior of a running system. This is essential for highly dynamic software that needs to interact with objects whose structure and behavior are not known when the application is written. Software analysis tools, like debuggers, are a typical example. Oddly, although reflection essentially concerns run-time entities, reflective applications tend to focus on static abstractions, like classes and methods, rather than objects. This is phenomenon we call the object paradox, which makes developers less effective by drawing their attention away from run-time objects. To counteract this phenomenon, we propose a purely object-centric approach to reflection. Reflective mechanisms provide object-specific capabilities as another feature. Object-centric reflection proposes to turn this around and put object-specific capabilities as the central reflection mechanism. This change in the reflection architecture allows a unification of various reflection mechanisms and a solution to the object paradox. We introduce Bifr\"ost, an object-centric reflective system based on first-class meta-objects. Through a series of practical examples we demonstrate how object-centric reflection mitigates the object paradox by avoiding the need to reflect on static abstractions. We survey existing approaches to reflection to establish key requirements in the domain, and we show that an object-centric approach simplifies the meta-level and allows a unification of the reflection field. We demonstrate how development itself is enhanced with this new approach: talents are dynamically composable units of reuse, and object-centric debugging prevents the object paradox when debugging. We also demonstrate how software analysis is benefited by object-centric reflection with Chameleon, a framework for building object-centric analysis tools and MetaSpy, a domain-specific profile

    Prévention et détection des interférences inter-aspects (méthode et application à l'aspectisation de la tolérance aux fautes)

    Get PDF
    La programmation orientĂ©e aspects (POA) sĂ©pare les diffĂ©rentes prĂ©occupations composant un systĂšme informatique pour amĂ©liorer la modularitĂ©. La POA offre de nombreux bĂ©nĂ©fices puisqu'elle permet de sĂ©parer le code fonctionnel du code non-fonctionnel amĂ©liorant ainsi leur rĂ©utilisation et la configurabilitĂš des systĂšmes informatiques. La configurabilitĂ© est un Ă©lĂ©ment essentiel pour assurer la rĂ©silience des systĂšmes informatiques, puisqu elle permet de modifier les mĂ©canismes de sĂ»retĂ© de fonctionnement. Cependant le paradigme de programmation orientĂ©e aspect introduit de nouveaux dĂ©fis pour le test. Dans les systĂšmes de grande taille oĂč plusieurs prĂ©occupations non fonctionnelles cohabitent, une implĂ©mentation Ă  l'aide d'aspects de ces prĂ©occupations peut ĂȘtre problĂ©matique. Partageant le mĂȘme flot de donnĂ©es et le mĂȘme flot de contrĂŽle les aspects implĂ©mentant les diffĂ©rentes prĂ©occupations peuvent Ă©crire dans des variables lues par d'autres aspects ou interrompre le flot de contrĂŽle commun aux diffĂ©rents aspects empĂȘchant ainsi l'exĂ©cution de certains d'entre eux. Dans cette thĂšse nous nous intĂ©ressons plus spĂ©cifiquement aux interfĂ©rences entre aspects dans le cadre du dĂ©veloppement de mĂ©canismes de tolĂ©rance aux fautes implĂ©mentĂ©s sous forme d aspects. Ces interfĂ©rences sont dues Ă  une absence de dĂ©claration de prĂ©cĂ©dence entre les aspects ou Ă  une dĂ©claration de prĂ©cĂ©dence erronĂ©e. Afin de mieux maĂźtriser l assemblage des diffĂ©rents aspects composant un mĂ©canisme de tolĂ©rance aux fautes, nous avons dĂ©veloppĂ© une mĂ©thode alliant l'Ă©vitement Ă  la dĂ©tection des interfĂ©rences au niveau du code. Le but de l'Ă©vitement est d'empĂȘcher l'introduction d'interfĂ©rences en imposant une dĂ©claration de prĂ©cĂ©dence entre les aspects lors de l'intĂ©gration des aspects. La dĂ©tection permet d'exhiber lors du test les erreurs introduites dans la dĂ©claration des prĂ©cĂ©dences. Ces deux facettes de notre approche sont rĂ©alisĂ©es grĂące Ă  l utilisation d une extension d'AspectJ appelĂ©e AIRIA. Les constructions d'AIRIA permettent l instrumentation et donc la dĂ©tection des interfĂ©rences entre aspects, avec des facilitĂ©s de compilation permettant de mettre en Ɠuvre l Ă©vitement d interfĂ©rences. Notre approche est outillĂ©e et vise Ă  limiter le temps de dĂ©boguage : le testeur peut se concentrer directement sur les points oĂč une interfĂ©rence se produit. Nous illustrons notre approche sur une Ă©tude de cas: un protocole de rĂ©plication duplex. Dans ce contexte le protocole est implĂ©mentĂ© en utilisant des aspects Ă  grain fin permettant ainsi une meilleure configurabilitĂ© de la politique de rĂ©plication. Nous montrons que l'assemblage de ces aspects Ă  grain fin donne lieu Ă  des interfĂ©rences de flot de donnĂ©es et flot de contrĂŽle qui sont dĂ©tectĂ©es par notre approche d'instrumentation. Nous dĂ©finissons un ensemble d'aspects interfĂ©rant pour l'exemple, et nous montrons comment notre approche permet la dĂ©tection d'interfĂ©rences.Aspect-oriented programming (AOP) separates the different concerns of a computer software system to improve modularity. AOP offers many benefits since it allows separating the functional code from the non-functional code, thus improving reuse and configurability of computer systems. Configurability is essential to ensure the resilience of computer systems, since it allows modifying the dependability mechanisms. However, the paradigm of aspectoriented programming introduces new challenges regarding testing. In large systems where multiple non-functional concerns coexist, an AOP implementation of these concerns can be problematic. Sharing the same data flow and the same control flow, aspects implementing different concerns can write into variables read by other aspects, or interrupt the control flow involving various aspects, and thus preventing the execution of some aspects in the chain. In this work we focus more specifically on interference between aspects implementing fault tolerance mechanisms. This interference is due to a lack of declaration of fine-grain precedence between aspects or an incorrect precedence declaration. To better control the assembly of the various aspects composing fault tolerance mechanisms, we have developed a method combining avoidance of interferences with runtime detection interferences at code level. The purpose of avoidance is to prevent the introduction of interference by requiring a statement of precedence between aspects during the aspects integration. Detection allows exhibiting during the test, errors introduced in the precedence statement. These two aspects of our approach are performed through the use of an extension called AspectJ AIRIA. AIRIA s constructs allow instrumentation and therefore the detection of interference between aspects, with facilities compilation to implement the interference avoidance. Our approach is designed and equipped to limit the debugging time : the tester can focus directly on the points where an interference occurs. Finaly, we illustrate our approach on a case study : a duplex replication protocol. In this context, the protocol is implemented using fine grained aspects allowing a better configurability of the replication policy.We show that the assembly of these fine-grained aspects gives rise to interference data flow and control flow that are detected by our instrumentation approach. We define a set of interfering aspects in this example, and show how our approach allows the detection of interferences.TOULOUSE-INP (315552154) / SudocSudocFranceF

    Prévention et détection des interférences inter-aspects : méthode et application à l'aspectisation de la tolérance aux fautes

    Get PDF
    La programmation orientĂ©e aspects (POA) sĂ©pare les diffĂ©rentes prĂ©occupations composant un systĂšme informatique pour amĂ©liorer la modularitĂ©. La POA offre de nombreux bĂ©nĂ©fices puisqu'elle permet de sĂ©parer le code fonctionnel du code non-fonctionnel amĂ©liorant ainsi leur rĂ©utilisation et la configurabilitĂš des systĂšmes informatiques. La configurabilitĂ© est un Ă©lĂ©ment essentiel pour assurer la rĂ©silience des systĂšmes informatiques, puisqu’elle permet de modifier les mĂ©canismes de sĂ»retĂ© de fonctionnement. Cependant le paradigme de programmation orientĂ©e aspect introduit de nouveaux dĂ©fis pour le test. Dans les systĂšmes de grande taille oĂč plusieurs prĂ©occupations non fonctionnelles cohabitent, une implĂ©mentation Ă  l'aide d'aspects de ces prĂ©occupations peut ĂȘtre problĂ©matique. Partageant le mĂȘme flot de donnĂ©es et le mĂȘme flot de contrĂŽle les aspects implĂ©mentant les diffĂ©rentes prĂ©occupations peuvent Ă©crire dans des variables lues par d'autres aspects ou interrompre le flot de contrĂŽle commun aux diffĂ©rents aspects empĂȘchant ainsi l'exĂ©cution de certains d'entre eux. Dans cette thĂšse nous nous intĂ©ressons plus spĂ©cifiquement aux interfĂ©rences entre aspects dans le cadre du dĂ©veloppement de mĂ©canismes de tolĂ©rance aux fautes implĂ©mentĂ©s sous forme d’aspects. Ces interfĂ©rences sont dues Ă  une absence de dĂ©claration de prĂ©cĂ©dence entre les aspects ou Ă  une dĂ©claration de prĂ©cĂ©dence erronĂ©e. Afin de mieux maĂźtriser l’assemblage des diffĂ©rents aspects composant un mĂ©canisme de tolĂ©rance aux fautes, nous avons dĂ©veloppĂ© une mĂ©thode alliant l'Ă©vitement Ă  la dĂ©tection des interfĂ©rences au niveau du code. Le but de l'Ă©vitement est d'empĂȘcher l'introduction d'interfĂ©rences en imposant une dĂ©claration de prĂ©cĂ©dence entre les aspects lors de l'intĂ©gration des aspects. La dĂ©tection permet d'exhiber lors du test les erreurs introduites dans la dĂ©claration des prĂ©cĂ©dences. Ces deux facettes de notre approche sont rĂ©alisĂ©es grĂące Ă  l’utilisation d’une extension d'AspectJ appelĂ©e AIRIA. Les constructions d'AIRIA permettent l’instrumentation et donc la dĂ©tection des interfĂ©rences entre aspects, avec des facilitĂ©s de compilation permettant de mettre en Ɠuvre l’évitement d’interfĂ©rences. Notre approche est outillĂ©e et vise Ă  limiter le temps de dĂ©boguage : le testeur peut se concentrer directement sur les points oĂč une interfĂ©rence se produit. Nous illustrons notre approche sur une Ă©tude de cas: un protocole de rĂ©plication duplex. Dans ce contexte le protocole est implĂ©mentĂ© en utilisant des aspects Ă  grain fin permettant ainsi une meilleure configurabilitĂ© de la politique de rĂ©plication. Nous montrons que l'assemblage de ces aspects Ă  grain fin donne lieu Ă  des interfĂ©rences de flot de donnĂ©es et flot de contrĂŽle qui sont dĂ©tectĂ©es par notre approche d'instrumentation. Nous dĂ©finissons un ensemble d'aspects interfĂ©rant pour l'exemple, et nous montrons comment notre approche permet la dĂ©tection d'interfĂ©rences. ABSTRACT : Aspect-oriented programming (AOP) separates the different concerns of a computer software system to improve modularity. AOP offers many benefits since it allows separating the functional code from the non-functional code, thus improving reuse and configurability of computer systems. Configurability is essential to ensure the resilience of computer systems, since it allows modifying the dependability mechanisms. However, the paradigm of aspectoriented programming introduces new challenges regarding testing. In large systems where multiple non-functional concerns coexist, an AOP implementation of these concerns can be problematic. Sharing the same data flow and the same control flow, aspects implementing different concerns can write into variables read by other aspects, or interrupt the control flow involving various aspects, and thus preventing the execution of some aspects in the chain. In this work we focus more specifically on interference between aspects implementing fault tolerance mechanisms. This interference is due to a lack of declaration of fine-grain precedence between aspects or an incorrect precedence declaration. To better control the assembly of the various aspects composing fault tolerance mechanisms, we have developed a method combining avoidance of interferences with runtime detection interferences at code level. The purpose of avoidance is to prevent the introduction of interference by requiring a statement of precedence between aspects during the aspects integration. Detection allows exhibiting during the test, errors introduced in the precedence statement. These two aspects of our approach are performed through the use of an extension called AspectJ AIRIA. AIRIA ‘s constructs allow instrumentation and therefore the detection of interference between aspects, with facilities compilation to implement the interference avoidance. Our approach is designed and equipped to limit the debugging time : the tester can focus directly on the points where an interference occurs. Finaly, we illustrate our approach on a case study : a duplex replication protocol. In this context, the protocol is implemented using fine grained aspects allowing a better configurability of the replication policy.We show that the assembly of these fine-grained aspects gives rise to interference data flow and control flow that are detected by our instrumentation approach. We define a set of interfering aspects in this example, and show how our approach allows the detection of interferences
    corecore