Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
MT311 Java Application Development and Programming Languages Li Tak Sing(李德成) Implementing subprograms When a subprogram is called, an activation record instance (ARI) is created in the stack. It is destroyed when the subprogram returns. An ARI has a number of fields. Dynamic link and static link are two of them. Both of them are pointers pointing to the ARI of other subprograms. The meaning of the names reflects that the former needs information in execution time and the latter only needs information in compilation time. Implementing subprograms In fact, the dynamic link of a subprogram always points to the ARI of the calling subprogram. As a subprogram can be called by different subprograms, to which ARI a dynamic link will point is not known at compile time. That is the reason why it is called dynamic. On the other hand, the static link of the ARI of a subprogram always points to the ARI of the static parent. Implementing subprograms This information is known at compile time and therefore is called static. ARI Other fields in ARI are parameters and local variables. So, consider the following subprogram: procedure proc1(int i) var j,k:integer; begin ..... end; ARI The ARI would have the following fields: – – – – – The storage for the parameter i (assume that it is passed by value) The storage for local variables j and k. The static link which points to the ARI of the static parent of the procedure. The dynamic link which points to the ARI of the calling procedure. return address ARI i j k s t at ic link dy namic link ret urn addres s point t o t he s t at ic parent point t o t he c alling s ubprogram ARI The ARI of the main program contains the following: – global variables 1. program A; 2. var a1: integer; 3. procedure B; 4. var b1: integer; 5. begin 6. ... 7 end; 8. procedure C; 9. var c1: integer; 10. procedure D; 11. var d1: integer; 12. begin 13. ... 14. end; 15. procedure E; 16. var e1: integer; 17. begin 18. C; 19. e1 := c1; 20. end; 21. begin 22. ... 23. end; 24. begin 25. ... 26. end; ARI Draw the ARIs if the at this moment we have the following procedure call sequence: – A -> E ->C->D Object Oriented Programming the three fundamental concepts underlying object-oriented programming: – – – data abstraction; inheritance; and polymorphism. Data abstraction and encapsulation The encapsulation of an object is the representation of its most important features. For example, the encapsulation of a car may be a vehicle with four wheels. An abstract data type is the encapsulation of an object which includes all the subprograms that are used to manipulate it. Data abstraction and encapsulation If all users of the object were restricted from manipulating it using these subprograms only, then the users’ code would be independent of the implementation of the object. This has two advantages: – The implementation of the abstract data type can be changed without affecting the users’ code. Thus these changes would not propagate to other parts of the system. This of course has one – condition, i.e., the interfaces of the subprograms should remain unchanged. The implementation of the object is naturally separated from other parts of the system. Therefore the object can be tested individually. This would increase the reliability of the system. Information hiding In order to ensure that users of an abstract data type manipulate it through a set of subprograms only, we have to find a way to prevent them from accessing the data structure of the data type directly. This is done by enforcing information hiding, i.e., removing the information concerning the internal attributes of the data type from any files released to the users. Information hiding In Java, this is done by access modifier. Inheritance and polymorphism Inheritance allows the programmer to inherit or derive new classes from an existing one. The new class may have additional attributes and methods. A new method would override an old one if the same name and parameter list were used. Overriding an existing method in a derived class is an important mechanism in fine-tuning an existing code. Inheritance and polymorphism However, this mechanism would not be of much use without polymorphism. Polymorphism is the ability to invoke the correct version of an overridden method when the corresponding message is passed to an object. Polymorphism is closely related to dynamic binding. Dynamic binding Dynamic binding means that the binding of a value to an item is to be done when a program is run. In this case, when a method of an object is invoked, the runtime environment will first check the true type of the object and then invoke the method that is defined for this object type. Inheritance and polymorphism Inheritance and polymorphism are important in making software reusable. Without them, existing code could hardly be reusable because situations change from project to project. With inheritance and polymorphism, we can fine-tune an existing code by deriving new classes and add new attributes, new methods and override existing methods in the new classes. Inheritance and polymorphism Polymorphism would ensure that the overridden methods would be invoked correctly. Functional and logic programming languages In procedural languages, we specify 'how' to perform a task. In functional and logic programming languages, we specify 'what' to perform in a task. Functional programming In functional programming languages, a program just consists of the definitions of a number of functions. Each function is defined more like a mathematical function than a C function. A C function usually describes how a value of the function can be calculated. A mathematical function definition, on the other hand, would contain the expressions that are used to calculate the value of the function. Functional programming Thus, the most important action in a functional programming language is the evaluation of expressions, while the actions in an imperative language are more diversified, including transferring control to a different place in the program, changing the value of a variable, etc. Functional programming For example, let's consider the problem of finding the sum of an array of integers. The C implementation of the function sum is shown below: int sum(int num[],int nopoint) { int tmp=0; int i; for (i=0;i<nopoint;i++) tmp+=num[i]; return tmp; } Functional programming We can see that this definition describes how the sum can be found by adding each element of the array to a temporary variable. At the end, this temporary variable would be the required sum. Now let’s consider the mathematical definition of the function. The following definition is the sum function which accepts a sequence of integers as parameters. Functional programming Functional languages where car, cdr are pre-defined functions which return the first element and the remaining list with the first element removed respectively. This mathematical definition is readily translated into any functional programming language. The following fragment of code shows how this is done in Scheme, a language we will talk about later. Functional languages Fundamentals of functional programming languages Purely functional programming languages define the outputs of a program as a mathematical function of the inputs. They have a number of features: – – Assignment of variables is prohibited within function definitions. Therefore there is no side effect in calling a function. As only expressions are needed in defining a function, there is no need to have loop constructs in these languages. Fundamentals of functional programming languages – – – Still there is a need for selection constructs because different expressions have to be selected under different conditions. Lists are important because they can easily be manipulated by operating on their first element and the remainder of the list. Recursion is important because it is the only means of doing operations repeatedly. Scheme In Scheme, the most important data structure is the list. The elements of a list can be atoms or other lists. Atoms can be bound or unbound. Bound atoms are those that have been bound to a value either by the language designer or by the programmer. Scheme They include numbers, Boolean values, and names that have been bound using the DEFINE function. Unbound atoms are used simply as literal constants. They mean anything that the programmer wants them to mean. Scheme The Scheme interpreter will try to evaluate every item it encounters unless it is told not to do so. When the interpreter evaluates a list, it will treat the list as a function so that the first element of the list is the function name and all other elements are parameters. It will evaluate all the parameters first and then pass the parameters to the function specified by the first element of the list. Scheme When the interpreter evaluates a bound atom, its value will be returned. When the interpreter evaluates an unbound atom, a run time error will occur. Scheme To tell the interpreter to leave an item alone, we have to precede that item with a single quote. Adding a single quote in front of an item is equivalent to passing that item to the primitive function quote. Thus the following two statements are exactly the same: ‘(1 2 3) (quote (1 2 3)) Scheme Both statements will be evaluated to the list (1 2 3). If the single quote were not there, then the interpreter would try to pass the two parameters 2 and 3 to the function 1. This is an error as 1 is not a function. Thus, unbound atoms should either be preceded by a single quote or be in a list that has been left alone by the interpreter. Scheme When a list is formed from some operations or has been preceded by a single quote, it will not be interpreted as a function. To interpret the list as a function, we have to pass the list to the eval function explicitly. Scheme list is a primitive function which forms a list from the given parameters. Thus, ‘(1 2 3) is equivalent to (list 1 2 3). Both would produce a list with three elements, 1, 2 and 3. However, the two forms are not the same in all cases. For example, consider the following two statements: Scheme ‘(1 (+ 1 2) 3) (list 1 (+ 1 2) 3) The first statement would be evaluated to a list with elements 1, (+ 1 2) and 3. The second statement would be evaluated to a list with elements 1, 3 and 3. This is because the single quote in the first statement has prevented the interpreter from evaluating any Scheme element of the list, and thus the second element is still a list. However, for the second statement, all of its parameters would be evaluated. The second element would be evaluated to 3. Then the three parameters would form a list. Scheme If we want to form a list with three unbound atoms, a, b and c, using the single quote method, we can write it as ‘(a b c). However, if we wanted to use the LIST function, we would write it as (list ‘a ‘b ‘c). Numerical operations Scheme has primitive functions for the basic numerical operations. (= x1 x2 x3 …) (< x1 x2 x3 …) (> x1 x2 x3 …) (<= x1 x2 x3 …) (>= x1 x2 x3 …) Numerical operations These functions return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing. For example, Numerical operations (= 1 1 1 1) ;returns #t (> 4 4 2 1) ;returns () (>= 4 4 2 1) ;returns #t (<= 1 2 2 4) ;returns #t Numerical operations The primitive functions: (+ x ...) (* x ...) calculate the sum or product of their arguments. For example: Numerical operations (+ 3 4.2) ;returns 7.2 (+) ;returns 0 (* 3 4.2) ;returns 12.6 (*) ;returns 1 With two or more arguments, the primitive functions: (- x1 x2 ...) (/ x1 x2 ...) Numerical operations return the difference or quotient of their arguments, associating to the left. With one argument, however, they return the additive or multiplicative inverse of their argument. For example, (- 3 2) ;returns 1 (- 3 4 5) ;returns -6 (- 4) ;returns -4 Numerical operations The functions: (exp x) returns ex (log x) returns ln(x) (sin x) returns sin(x) (cos x) returns cos(x) (tan x) returns tan(x) (asin x) returns sin-1(x) Numerical operations (sqrt x) returns x (expt x1 x2) returns x1x2 are also available in Scheme.