Implementation of generic programming in non-C ++ languages

Source: Internet
Author: User

Implementation of generic programming in non-C ++ languages
Zuo Qinghou
2001.9.22

GP (generic programming, generic programming) is called another revolution in programming ideas. However, the discussion on GP is generally based on the C ++ language. So can Gp be implemented in other programming languages? This is a question that the author has been thinking about, because the level is limited and the information is scarce, there is little to gain. Some immature ideas have been sorted out.
This article takes Delphi as an example (Java is similar, for reference) to discuss another idea of GP implementation. The code is written without verification.
According to the author's understanding, the key to implementing GP lies in implementing ADT (abstract data type, abstract data type ). Only when ADT is implemented can a specific data type be separated from a common algorithm.
In C ++, ADT storage is implemented through templates. The following is a simple stack example (the implementation section is not provided ):
  
Template <class type> class Stack {
Public:
Void push (const type & item );
Type pop;
...
}

Stack applications:
  
Stack <int> S;
Int data;
Data = 1;
S. Push (data); file: // inbound Stack

Int out;
Out = S. Pop; file: // output Stack

An int-type stack object is created to store int-type data.
However, in Delphi/Java, there is no template mechanism. So how to implement ADT? Different from C ++, the class inheritance system of Delphi/Java is a single structure, that is, in Delphi, all classes are forced by the compiler to be subclasses of tobject (Objects in Java ). This tobject can be viewed as the highest-level abstraction of all classes. So can we assume that Delphi/Java already provides ADT support first?
Try to use this idea to build a stack:
  
Tstack = Class
Public
Procedure push (item: tobject );
Function POP: tobject;
...
End;

This tstack class operates on tobject objects. However, this class cannot be applied immediately, because in Delphi, simple data types are not objects. Therefore, a custom data type must be created. The following creates a custom data type with only one integer member:
  
Tadt = Class
Public
Data: integer;
End;
  
Let's look at the stack application:
  
VaR
STACK: tstack;
Adt1, adt2: tadt;
Begin
STACK: = tstack. Create;
Adt1: = tadt. Create;
Stack. Push (adt1); file: // inbound Stack

Adt2: = stack. Pop as tadt; file: // output Stack

Stack. Free;

This completes the storage of ADT objects. Note that the ADT object is directly imported into the stack when the stack is imported, because the tstack class operates on the tobject, because of the single structure of Delphi, any type of objects can be assigned to variables of the tobject type. However, when the stack is output, the returned value is also a tobject variable. Therefore, you must use as to perform a downward ing. Thanks to a single structure, Delphi/Java provides strong support for rtti, so this downward ing is easy. However, there is no doubt that rtti has lost some efficiency.
After ADT storage is implemented, how can we perform operations on ADT?
In C ++, Operator Overloading is used to solve this problem. Let's look at an example:
In a list class, perform the search operation:
  
Template <class type> class list {
Type * Find (type & value); file: // find the specified data item. If it is found, its address is returned. Otherwise, null is returned.
...
}

Template <class type> type * List <type>: Find (type & Value ){
Type * P = first-> link;
Where (P! = NULL &&! (P-> DATA = value )){
P = p-> link;
}
Return P;
}

In the implementation of the find function of the List class, the code is copied from the linked list structure, so you do not need to care about its details. Note that there is only one place, that is, p-> DATA = value in the judgment condition. Since p-> data and value are both ADTs, they may be simple data or any custom data type when creating a list object. However, you can still use the = Operator to operate on them. Why? The reason is that the operator is overloaded.
The following uses a point class to illustrate this point:

Class Point {
PRIVATE:
Int X, Y;
Public:
Int operator = (const point & Point); file: // checks whether two point objects are equal
...
}

Int point: Operator = (const point & Point ){
If (x = point. X & Y = poing. Y ){
Return 1;
} Else {
Return 0;
};
}

We can see that, because the = Operator is overloaded, two point objects can be compared. Similarly, as long as the corresponding operators are reloaded for any data type, they can be uniformly operated by the container class.
When you turn to non-C ++ again, the problem arises again: Delphi/Java does not support Operator overloading. As a remedy, you can use functions instead of operators. For example, use the equals function to replace =. However, the bigger problem is that the object operated by the container class is tobject, and tobject does not have the equals method. (In Java, the object has the equals method, but there is no other complete calculation method .)
Without changing the existing Syntax of Delphi/Java, the solution that the author can think of is to create a tadt class as the base class of all data structures. Tadt defines many abstract methods such as equals and Add. All custom data types are derived from tadt and corresponding methods are reloaded. The container class only needs to operate on tadt to implement general algorithms. However, this solution is not ideal.
(In addition, Delphi provides some general container classes, such as tlist, tcollection, tstack, and tqueue. However, unlike what is mentioned in this article, they store not tobject, but pointer. Because of Delphi's "reference object model" mechanism, storing tobject objects is actually equivalent to storing a pointer. The difference is that pointer can not only store objects, but also store basic data types. This should also be the reason why Borland was designed like this. However, these container classes only provide management methods such as add and delete, and do not provide general algorithms, because you cannot perform complex operations on pointer. In practice, programmers usually send a new class from the container class, or maintain a container class in their own class. This is also a solution, but the algorithm cannot be independent .)
  
To sum up, the author's point of view is as follows:
1. In C ++, ADT storage is implemented through the template mechanism. Delphi/Java can also be implemented through a single structure + rtti mechanism. The difference is that the implementation of C ++ is syntactic, while that of Delphi/Java is logical. That is to say, C ++ is implemented through a set of special syntaxes, delphi/Java is implemented based on OOP theory and its own class library system. From this perspective, the implementation mechanism of Delphi/Java is simpler and more intuitive.
2. In terms of running efficiency, C ++ must be better than Delphi/Java, because the implementation of C ++ is in the compilation period, while Delphi/Java is in the runtime period. The use of rtti will have a significant impact on efficiency. However, from another perspective, the implementation of ADT in the runtime also brings benefits, that is, the data structure type stored by the container class can be changed at will during the runtime. The author has not considered the substantial consequences of this "Data Type polymorphism" on programming. However, imagine that the standard algorithms may be encapsulated in compiled modules such as DLL, or even the COM objects provided by the OS, the programmer only needs to create his own data type and submit it to the corresponding interface? ......
3. In C ++, the ADT operation is implemented through Operator overloading. In Delphi/Java that does not support Operator overloading, the author fails to find a good replacement method. The solution to establishing a unified ADT abstract class can only be said to be a bad idea. :-(Some programmers prefer to add Operator Overloading in Delphi. This should be one of the reasons. I don't know whether Borland attaches importance to this. In addition, it is said that the next version of Java will fully support GP. I don't know what mechanism is used for implementation? For more information, see the introduction.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.