Towards flexible Integrated Development Environment
BACKGROUND
This thesis is about the application of cloud computing to software language engineering. We start this chapter by defining what a software language is (Section 3.1) and giving an overview of software language engineering (Section 3.1.1) before introducing the notion of metamorphic DSL (Section 3.1.2). We then introduce the principles of cloud computing (Section 3.2) and describe its different service models (Section 3.2.1). We conclude by presenting the properties of cloud-native applications (Section 3.2.2) and their realization in microservices (Section 3.2.3).
Software Language
Software languages are artificial languages implemented as software. They are involved in every activity of software and systems engineering [91] and are more and more numerous [90]. Software languages can be programming languages (e.g., C, Python, Javascript) but are not restricted to this domain. We can cite for example markup languages to structure documents (e.g., HTML, XML), query languages to request databases (e.g., SQL), configuration languages (e.g., YAML, JSON), modeling languages (e.g., Flowchart, ThingML), etc. Software languages can be classified as General-Purpose Languages (GPL) or DomainSpecific Languages (DSL) [145]. GPLs are software languages general enough to target any application domain. It means that they don’t contain features specialized for a particular domain. They are intended to be used by software-experts, which can make them difficult to handle by domain-experts who do not have the same skills. DSL suit better for domain-experts since they are languages at the right level of abstraction for them, making them easier for modifications and understanding [32]. DSLs are everywhere: web, embedded systems, simulation, security, testing, or education to cite a few domains where they are used [112]. Compared to GPLs, DSLs are tailored for one 23 Partie I, Chapter 3 – Background particular application domain and have expressiveness that increases their ease of use [101]. DSLs might also improve language user efficiency [87] however their is a lake of usability evaluation [12]. Software languages can also be classified as internal or external languages. Internal languages are software languages using the constructs of host languages to express the concepts of their domain. Internal languages benefit from the tooling of the host language [72]. This makes it possible to reuse the existing infrastructure of the host language to avoid reimplementing it specifically for the internal language, and thus reduces the development cost. Reusing tools of the host language is also a limitation in the sense that they are not specifically tailored for the internal language, e.g., a source code validator may not detect errors specifics to the internal language. Fluent API [48] is an example of a technique used to implement internal languages in programming languages. This technique relies mostly on method chaining, object scoping and call of function as function’s parameters. External languages are autonomous languages in the sense that they have their own dedicated tooling. The creation of an external language is the creation of a new language that requires writing its specification and implementing its tooling. In the following section, we present the discipline of Software Language Engineering, which provides methods and techniques for software language development activities.
Software Language Engineering
Software Languages are software [45] and therefore face the same challenges in their development (e.g., design, test, deployment, maintenance, etc). The development tasks can even increase in complexity for the case of DSLs since it requires expertise in both application domain and language development [101]. The construction of domain-specific tools is expensive [149] and require language engineering skills [154]. Derived from Software Engineering, Software Language Engineering is the computing discipline for designing and implementing Software Languages. It is a systematic discipline providing methods to guide the language designers in the design and implementation of the aspects of a software language which mainly consist of the abstract syntax, the concrete syntax, and the semantics [60]. Figure 3.1 shows the relationships between these three aspects of software languages. The central aspect is the Abstract Syntax that structurally defines the concepts of a language, e.g., a metamodel. The Abstract Syntax is possibly complemented by Concrete Syntaxes that define how the concepts of a language will be presented to the language users, e.g., a textual grammar. The Abstract Syntax can also be completed by Semantics that add meaning, e.g., well-formedness rules. We detail these three software language aspects in the following. An abstract syntax defines, for a given language, the concepts and their relationships. Concepts are used as language constructs to create the representation of a system of the application domain. Metamodels and models (i.e., a graph of objects) are examples of forms that such abstract syntax and representations can take. Language users manipulate representations through language services provided by the tooling of the language. However, these representations are not what the language users see since they are abstract data structures, meaning they are independent of concrete representations constructed thanks to the concrete syntax. Figure 3.2 illustrates the definition and the usage of an abstract syntax for the Finite State Machine (FSM) language. The top sub-figure 3.2a presents the abstract syntax of the FSM language in the form of a metamodel. It define the three concepts of the language with the classes FSM, State, and Transition. The FSM is composed of States and Transitions, and has a reference to one State that design it has the initial state of the machine. A Transition has a reference to an ingoing State, a reference to an outgoing State and has an attribute event to define its trigger. Both FSM and State have an attribute name. The bottom sub-figure 3.2b presents an example of FSM representing the behavior of a door, in the form of a model conform to the metamodel presented in sub-figure 3.2a. The door is represented by an object FSM named ’door’. It has two objects State named ’opened’ and ’closed’, the former being referenced has the initial State. The ob25 Partie I, Chapter 3 – Background (a) Abstract syntax of the FSM language, in the form of a metamodel (b) The behavior of a door represented by a model conform to the metamodel of the FSM language Figure 3.2 – Illustrative example of definition and usage of an abstract syntax with the Finite State Machine language ject FSM contains also two objects Transition. The first Transition ingoing from the State named ’opened’, outgoing to the State named ’closed’ and is triggered by the event ’close’. The second Transition ingoing from the State named ’closed’, outgoing to the State named ’opened’ and is triggered by the event ’open’. A concrete syntax defines the notations for representations presented to the language users. It is through these notations that the language users will understand and manipulate the abstract representations. The concrete syntax can be textual or graphical. Textual syntaxes are defined by textual grammars, i.e., production rules like EBNF [156]. Graphical syntaxes are defined by mapping elements of the abstract syntaxes with graphical representations like geometrical shapes, tables, etc [147, 151]. Listing 3.1 shows an illustrative concrete syntax for the Finite State Machine language in the form of a grammar. It is composed of production rules that define that 26 3.1. Software Language 1 grammar FSM; 2 3 fsm : ’fsm ’ ’ { ’ s t a t e * t r a n s i t i o n * ’ } ’ ; 4 s t a t e : ’ s t a t e ’ ID ; 5 t r a n s i t i o n : ID ’→’ ID ; 6 7 ID : [ a−z ] + ; Listing 3.1 – Illustrative example of concrete syntax with the Finite State Machine language an FSM starts with the word fsm followed by a list of states and a list of transitions surrounded by curly brackets. A state must start with the word state followed by an identifier and a transition starts with an identifier followed by an arrow and another identifier. An identifier is defined as a sequence of at least one letter. In addition to abstract syntax and concrete syntax to define languages, they are semantics that gives meaning to the language. Semantics are classified in static semantics or dynamic semantics. Static semantics are attached to language constructs and are about checking their well-formedness. Dynamic semantics is about computation and express the runtime behavior of languages. It can be one kind of operational, denotational or axiomatic, or hybrid [109]. Operational semantics defines language behavior with transitions between program states. The evaluation of operational semantics is the run of a sequence of steps that perform transformations of the program state. Denotational semantics defines the mapping between two languages. It is used to translate the constructs of a source language to constructs of a target language. Axiomatic semantics consists of making assertions on programs. It is used to define the properties of programs that have to be satisfied, e.g., by using Hoare logic [69]. Language workbenches are IDEs assisting language designers in the engineering of languages and improving the user experience of these languages [49]. In addition to tools and methods guiding language designers during the development, they provide metalanguages to specify the different concerns of software languages. Erdweg et al. [42] compared languages workbenches and proposed a feature model summarizing their different concerns. To give some examples of language workbenches, we can cite Gemoc [16], Xtext [15], Rascal [84], Spoofax [78] or JetBrains MPS.
Metamorphic DSL
When coming to implementing a DSL, language designers have to take design decisions. First of all, the language designer has to choose a shape for the DSL. The shape of a language is realized through a technological stack providing the means to implement the different concerns of a language. A good shape of a language depends on its user and its activity [28]. For example, an internal language, like an API is easily integrated with programs and therefore more suited for a programmer whereas an external form may be more intuitive for a non-software-expert. The decision on how to implement a DSL can also be based on the facilities provided by the language workbenches, each of which has strength in a particular concern of a language. For example, a language workbench like Rascal eases the implementation of refactoring tools. The notion of metamorphic DSL was introduced in [3]. It is the idea that a DSL can have multiple shapes at the same time and that language users can switch between the shapes. Metamorphic DSL benefits both language designers who can leverage the strength of multiple technological stacks to implement a language (i.e., a shape) and language users who can use the most appropriate shape according to their activities. 1 SELECT * 2 FROM produc ts 3 WHERE gps = ’ t rue ’ (a) SQL as external language 1 Op tional person = 2 from ( Produc t . c l a s s ) 3 . where ( Produc t : : getGPS ) 4 . equ al s ( » t ru e » ) 5 . s e l e c t ( 6 productMapper , 7 c onne c ti on F a c t o r y : : openConnection ) ; (b) SQL as fluent API Figure 3.3 – Illustrative example of metamorphic SQL with an external language shape and a fluent API shape Figure 3.3 shows an illustrative example of metamorphic DSL with the Structured Query Language (SQL), a language to write queries for databases. In this example, SQL as metamorphic language has two shapes: one as an external language and one as a fluent API in Java. Both sub-listings 3.3a and 3.3b show the same query (the selection of all products with the GPS property) in the two shapes of the metamorphic language. The both shapes of the metamorphic SQL are useful to the user but for different tasks. The strength of the external language shape is that the user can benefits of a dedicated to write the queries. The fluent API shape offer to the user the opportunity to use the host language to build its queries (e.g., using Java’s for loops, variables, if, etc). In the previous sections, we presented what are software languages, SLE, and metamorphic DSL. We will then present the field of Cloud Computing, which is used as a means in this thesis to distribute language services, allowing to leverage of multiple execution platforms.
1 Résumé en français |