AbstractThis article provides an overview of a pattern-based programming system, named Panda, for automatic generation of high-level programming language code. Many code generation systems have been developed [2, 3, 4, 5, 6] that are able to generate source code by means of templates, which are defined by means of transformation languages such as XSL, ASP, etc. But these templates cannot be easily combined because they map parameters and code snippets provided by the programmer directly to the target programming language. On the contrary, the patterns used in a Panda program generate a code model that can be used as input to other patterns, thereby providing an unlimited capability of composition. Since such a composition may be split across different files or code units, a high degree of separation of concerns [15] can be achieved. A pattern itself can be created by using other patterns, thus making it easy to develop new patterns. It is also possible to implement an entire programming paradigm, methodology or framework by means of a pattern library: design patterns [8], Design by Contract [12], Aspect-Oriented Programming [1, 11], multi-dimensional separation of concerns [13, 18], data access layer, user interface framework, class templates, etc. This way, developing a new programming paradigm does not require to extend an existing programming system (compiler, runtime support, etc.), thereby focusing on the paradigm concepts. The Panda programming system introduces a higher abstraction level with respect to traditional programming languages: the basic elements of a program are no longer classes and methods but, for instance, design patterns and crosscutting concerns [1, 11]. 1 INTRODUCTIONSoftware programming based on traditional programming languages (such as C, C++, Lisp, Prolog, Java, C#, etc.) is graphically represented in Figure 1 (where the C# programming language has been used). Figure 1: Manual coding process. Such languages differ under several aspects:
However, the size of equivalent real programs is not very different from language to language. In other words, traditional programming languages are not able to automate common repetitive programming tasks. Many code generation systems have been developed [2, 3, 4, 5, 6] that are able to generate source code by applying code templates, which are defined by means of transformation languages such as XSL, ASP, etc. This new programming model is sketched in Figure 2 (where the target programming language is C#).Figure 2: Traditional code generation process. Such code generation systems are able to generate very sophisticated code snippets, including complete programs, in a variety of programming languages. Nevertheless, these code templates cannot be easily combined because they map parameters and code snippets provided by the programmer directly to the target programming language. In order to modify or extend the generated code, the programmer may edit either the template code or directly the generated code. The former approach may require a deep understanding of the template structure; furthermore, the template source code could not be available. The latter option is suitable for small changes since the transformation engine cannot be exploited; furthermore, such changes have to be repeated if the template is applied again, due to changes in the template parameters or in the template code itself. However, some of the code generation systems are able to keep certain kinds of manual changes to the generated code if the template is applied afterwards. Moreover, template code itself could benefit by the transformation engine, but code generation systems do not usually provide support for meta-templates which generate code templates. Panda (Pattern Network Development Assistant) is a pattern-based programming system for automatic generation of high-level programming language code. This system attempts to inherit the capability to automate repetitive programming tasks from traditional code generation systems together with the expressive power of programming languages. A Panda pattern may be classified as functional or procedural. A functional pattern generates an instance of a code model that can be used as input to another functional pattern or may be modified by a procedural pattern, thereby providing an unlimited capability of composition (see Figure 3).Figure 3: Panda code generation process. Since such a composition may be split across different files or code units, a high degree of separation of concerns [15] can be achieved. In order to extend, for example, a Java programming environment with Design by Contract [12], several approaches have been followed, but nearly everyone makes use of a different technology, such as extending preprocessor, compiler or runtime support. Such approaches are very complex and most of development time is spent on integration details instead of focusing on the paradigm concepts. Moreover, two different paradigms that make use of different technologies cannot be likely used at the same time. On the contrary, Panda makes it possible to create a pattern itself by using other patterns, thus making it easy to develop new patterns. Moreover, an entire programming paradigm, methodology or framework can be easily implemented by developing a small library of patterns. As a consequence, Panda makes it possible to focus on the paradigm concepts instead of the implementation details. Furthermore, several paradigms may be used at the same time by simply joining the corresponding pattern libraries. Some examples of paradigms and frameworks that can be easily implemented in Panda follow:
2 SYSTEM ARCHITECTUREThe Panda programming system executes Panda programs by means of a runtime support (RTS), implemented in a given programming language or framework (RTSL). The RTS is responsible for connecting the elements of a Panda program, listed in the following:
.NET and Java are examples of RTSL. Some examples of patterns are listed in the following:
Some examples of code represented by RTSL objects follow:
Some examples of code processors are shown in the following:
Figure 3 illustrates an example of execution of a Panda program where the following elements are involved:
These elements will also be used in the examples described in the following sections. A Panda IDE (Integrated Development Environment) implementing such elements is available for download from the Panda Web site [14]. 3 EXAMPLES OF PANDA PROGRAMSSome examples of Panda programs which generate C# code are described in this section. The first example is a very simple program which represents an empty class (Player1) by using the functional EmptyClass pattern:
Such a program generates the following C# code: This simple example corresponds to the typical philosophy of traditional code generation systems. By using the procedural AddReadWriteField pattern together with the EmptyClass pattern, the following Panda program represents the Player2 class containing the Name property (the AddReadWriteField pattern adds a C# field together with a get/set property, given its name and type): that corresponds to the following C# code: This simple example is already sufficient to show the composition capabilities of the Panda language: the output of the EmptyClass pattern becomes one of the inputs of the AddReadWriteField pattern. The procedural AddCSharpMethod pattern can be used to add the ToString method: Pattern parameters can be specified either by name or position (see, respectively, the PropertyName parameter of the AddReadWriteField pattern and the ClassName parameter of the EmptyClass pattern). Primitive values (strings, numbers, source code in another programming language, etc.) are specified by using a delimiter character, which can be either the quote character (") or the sharp character (#). The square brackets are used for specifying a list of values. In order to improve the readability of a Panda program, the chain keyword can be used, that makes it possible to omit the assignment of the first parameter. For instance, the previous example can be improved as follows, where the SourceType parameter of the AddReadWriteField and AddCSharpMethod patterns is omitted: 4 EXAMPLE OF PATTERN CREATIONRTS-based patterns are mainly used for simple basic patterns (such as, for instance, the AddReadWriteField pattern) and performance-critical patterns (such as, for instance, the AddCSharpMethod pattern). A pattern may be defined by using a generic software development tool able to generate a module compatible with the RTSL. Alternatively, you can write a Panda program and use a code processor which generates modules compatible with the RTSL. In both cases, several coding conventions have to be followed (involving the base class and the public properties). Language-based patterns are mainly used for large pattern libraries (such as, for instance, a pattern library for generating a Web user interface), since they are more intuitive with respect to RTS-based patterns:
A typical example of code generation is described in this section: a strongly-typed C# collection [7]. The Stack1 pattern is defined as follows, where the functional pattern statement has been used: The StackClass class, together with the StackSlot nested class, represents a simple implementation of a stack containing generic objects of type ElementType. The definition of the Stack1 pattern makes use of the ExecuteCSharpFunction pattern, which compiles and executes the C# method specified in the Code parameter (the method's parameters are provided by means of the Parameters parameter). The object returned by the method (a TypeDefinition object in this case) is, in turn, returned by the ExecuteCSharpFunction pattern and, afterwards, by the Stack1 pattern. Therefore, the ExecuteCSharpFunction pattern makes it possible to achieve the same expressive power of RTS-based patterns without requiring a C# IDE, at the price of a worse performance. The ReplaceToken method (available in every class of the DotNetCode namespace for performing text replacements) is used to insert the name of the specific stack class and the name of the specific type of stack elements. The Stack1 pattern can be used in the following Panda program to generate a stack of Player objects:
Nevertheless, the implementation of the Stack1 pattern is not very different from an RTS-based pattern, since it is based on the ExecuteCSharpFunction pattern. Actually, the Stack1 pattern can also be implemented by combining basic patterns as follows: You can find other and more complex examples of pattern definitions in the Panda samples available for download from the Panda Web site [14]. Such patterns are used to generate a typical three-tier C# application, which makes use of the ADO.NET and Windows Forms frameworks. 5 EXAMPLES OF PANDA LIBRARIESThe following sections will explain how some widespread programming paradigms can be implemented by means of small pattern libraries. Multi-dimensional separation of concernsPanda can be used to achieve multi-dimensional separation of concerns [13, 18] (an evolution of Subject-Oriented Programming [9, 17]), which will be explained by means of a class hierarchy for parsing and processing a mathematical expression language [18]. Such a hierarchy is made up of the following classes: Expression, Number, BinaryOperator, Plus, Minus, UnaryOperator, UnaryPlus, UnaryMinus. For each class, the following virtual methods are defined, as well constructors and properties: Eval, SyntaxCheck, Display, Process. If a virtual method for semantic or style checking has to be added to this hierarchy, all classes have to be modified. The Visitor design pattern [8] achieves multi-dimensional separation of concerns, but it presents the following limitations:
Hyper/J [10] is a tool that extends the Java language with a support for multi-dimensional separation of concerns. This tool makes it possible to group Java code snippets into hyperslices which can be combined to generate the requested class hierarchy. In the mathematical expression example, the following hyperslices may be defined [18]:
together with a rule for composing them. Every slice contains a separate Java code snippet for each mathematical class, thus fully achieving separation of concerns. For example, if a Check virtual method for semantic checking has to be introduced, a new slice is added. If a new mathematical expression is introduced, all slices have to be modified, but by adding separate code snippets. Panda, too, is able to fully achieve separation of concerns in the following way:
The Kernel slice can be implemented in Panda as follows (constructors and properties have been omitted): The code of the Display slice follows, where the implementation of the methods has been omitted (the code of the Evaluation slice is analogous): The code of the Syntax Check slice follows (the implementation of the methods has been omitted): The names of the methods defined in the Semantic Check slice are identical to those defined in the Syntax Check slice. Therefore, the MergeMethods pattern renames the conflicting methods and creates a new method which calls them. Such a pattern is applied as follows: The resulting C# code follows (only the Expression and Number classes are shown): Aspect-Oriented ProgrammingAspect-Oriented Programming (AOP) [1, 11] is a programming paradigm for achieving separation of crosscutting concerns, such as tracing of method calls. A crosscutting concern is defined by an aspect, which is made up of a pointcut and an advice. A pointcut is a collection of joint points, each of which represents a point in the execution of a program, such as method calls, field assignments, etc. An advice specifies the code to be executed when one of the joint points is reached. AOP can be easily applied to several widespread concerns:
AOP can be easily implemented by means of a library of Panda patterns. One of them will be applied to a very simple mathematical library, whose methods may be called only if the library is properly licensed. Given the following Panda code which represents the C# classes of the mathematical library: the following Panda code adds license checking at the beginning of all public methods, by using the BeforeExecutionAspect AOP pattern: as shown by the resulting C# code: Design by ContractDesign by Contract [12] could be implemented by means of the AOP patterns presented in the previous section. However, creating a specific Panda pattern library simplifies the application of consistency checking. For example, the AddInvariantCondition pattern could be defined that adds a given condition involving the fields of a given class to the class itself (inside a method conventionally named Invariant), whereas the AddInvariantChecking pattern is used to execute the Invariant method in every public or internal method or property. These two patterns can be used to check the content of the m_Name field of the Player5 class: as shown by the resulting C# code: Design PatternsThe design patterns presented in [8] can be applied more easily by means of a Panda pattern library. For example, the Decorator design pattern applied to a drawing library is sketched in Figure 4.Figure 4: The Decorator design pattern. The VisualComponentDecorator class contains a field of type VisualComponent and a virtual method for each method of the VisualComponent interface. Such virtual methods provide the default behaviour of a decorator class, by forwarding any method call to the object of type VisualComponent. Hence, the BorderDecorator class overrides only the VisualComponent methods involved in drawing a border. The VisualComponentDecorator class can be generated automatically by means of a Panda pattern (AbstractDecorator), applied to the VisualComponent interface as follows: As a consequence, the definition of the IsEnabled method may be omitted from the definition of the BorderDecorator class: that generates the following C# code: 6 CONCLUSIONTha main benefit of the Panda programming system is to increase the abstraction level of software programs. Instead of talking about classes, fields, methods, etc., a Panda program is made up of decorators, tracing of method calls, data layers and user interfaces derived from a business layer, etc. Hence, adopting Panda requires a new approach to software development, that can be followed in different ways:
However, this is just the first stage of the Panda programming system, which could evolve in several directions:
REFERENCESAspectJ Web site: http://www.eclipse.org/aspectj/. [2] Code Generation Network Web site: http://www.codegeneration.net. [3] CodeCharge Web site: http://www.codecharge.com. [4] CodeSmith Web site: http://www.codesmithtools.com. [5] Codify Web site: http://www.workstate.com/codify/. [6] DeKlarit Web site: http://www.deklarit.com. [7] Ecma International. "C# Language Specification". Standard ECMA-334: http://www.ecma-international.org/publications/standards/Ecma-334.htm, 2006. [8] Gamma E., Helm R., Johnson R. and Vlissides J. "Design Patterns: Elements of Reusable Object-Oriented Software". Addison-Wesley, 1995. [9] Harrison W. and Ossher H. "Subject-Oriented Programming (A Critique of Pure Objects)". Proceedings of the eighth annual conference on Object-oriented programming systems, languages, and applications : 411-428, 1993. [10] Hyper/J Web site: http://www.alphaworks.ibm.com/tech/hyperj/. [11] Kiczales G., Lamping J., Mendhekar A., Maeda C., Lopes C., Loingtier J. and Irwin J. "Aspect-Oriented Programming". Proceedings of the European Conference on Object-Oriented Programming : 220-242, 1997. [12] Meyer B. "Object-Oriented Software Construction (2nd Edition)". Prentice-Hall, 1997. [13] Multi-Dimensional Separation of Concerns Web site: http://www.research.ibm.com/hyperspace/. [14] Panda Web site: http://www.softison.com/panda/. [15] Parnas D. L. "On the Criteria To Be Used in Decomposing Systems into Modules". Communications of the ACM, 15 (12): 1053-1058, 1972. [16] Stroustrup B. "The C++ Programming Language (3rd Edition)". Addison-Wesley, 1997. [17] Subject-Oriented Programming Web site: http://www.research.ibm.com/sop/. [18] Tarr P., Ossher H., Harrison W. and Sutton S. "N degrees of separation: multi-dimensional separation of concerns". Proceedings of the 21st international conference on Software engineering : 107-119, 1999. About the authors
Daniele Mazzeranghi: "Overview of the Panda Programming System", in Journal of Object Technology, vol. 7, no. 4, May-June 2008, pp. 67-99 http://www.jot.fm/issues/issue_2008_03/article1/ |
||||||||||