Programming Languages: Abstraction: Onur Tolga S Ehito Glu
Programming Languages: Abstraction: Onur Tolga S Ehito Glu
18 March 2008
Programming Languages:Abstraction
Outline
3 Parameters 1 Abstraction 4 Parameter Passing Mechanisms Function and Procedure Abstractions Copy Mechanisms Selector Abstraction Binding Mechanisms Generic Abstraction Pass by Name Iterator Abstraction 5 Evaluation Order 2 Abstraction Principle 6 Correspondence Principle
Abstraction
Iceberg: Details at the bottom, useful part at the top of the ocean. Animals do not care about the bottom. User: how do I use it?, Developer: How do I make it work? User: what does it do?, Developer: How does it do that? Abstraction: Make a program or design reusable by enclosing it in a body, hiding the details, and dening a mechanism to access it. Separating the usage and implementation of program segments. Vital large scale programming.
Abstraction is possible in any discipline involving design: radio tuner. Adjustment knob on a radio is an abstraction over the tuner element, frequency selection. An ATM is an abstraction over complicated set of bank transaction operations. Programming languages can be considered as abstraction over machine language. ...
Purpose
Details are confusing Details may contain more error Repeating same details increase complexity and errors Abstraction philosophy: Declare once, use many times! Code reusability is the ultimate goal. Parameterization improves power of abstraction
The computation of an expression is the detail (algorithm, variables, etc.) Function call is the usage of the detail Functions are abstractions over expressions void functions of C or procedure declarations of some languages No value but contains executable statements as detail. Procedures are abstractions over commands Other type of abstractions possible?
Selector abstraction
arrays: [..] int a[10][20]; a[i]=a[i]+1; operator selects elements of an array.
User dened selectors on user dened structures? Example: Selector on a linked list:
int & g e t ( L i s t *p , int e l ) { /* linked list */ int i ; for ( i =1; i < e l ; i ++) { p = p-> next ; /* take the next element */ } return p - > d a t a ; } g e t ( head , i ) = g e t ( head ,2) + 1; ...
Generic abstraction
Same declaration pattern applied to dierent data types. Abstraction over declaration. A function or class declaration can be adapted to dierent types or values by using type or value parameters.
template < class T> class L i s t { T content ; L i s t * next ; public : L i s t () { n e x t =NULL }; void add (T e l ) { ... }; T g e t ( int n) { ...}; }; template < class U> void swap (U &a , U &b) { U tmp; tmp= a ; a =b; b=tmp; } ... L i s t <int> a ; L i s t <double> b; L i s t <Person> c ; int t , x ; double v , y ; P e r s o n z ,w; swap ( t , x ); swap ( v , y ); swap ( z ,w);
Iterator abstraction
Iteration over a user dened data structure. Ruby example:
class T r e e def i n i t i a l i z e ( v ) @ v a l u e = v ; @ l e f t = nil ; @ r i g h t = nil end def t r a v e r s e @left . traverse {| v | yield v } if @ l e f t != nil yield @ v a l u e # block a r g u m e n t r e p l a c e s @ r i g h t . t r a v e r s e {| v | yield v } if @ r i g h t != nil end end a = T r e e .new (3) ; l =[] a . t r a v e r s e { | node | p r i n t node l << node }
Abstraction Principle
If any programming language entity involves computation, it is possible to dene an abstraction over it Entity Abstraction Expression Function Command Procedure Selector Selector function Declaration Generic Command Block Iterator
Parameters
Many purpose and behaviors in order to take advantage of declare once use many times. Declaration part: abstraction name(Fp1 , Fp2 , ..., Fpn ) Use part: abstraction name(Ap1 , Ap2 , ..., Apn ) Formal parameters: identiers or constructors of identiers (patterns in functional languages) Actual parameters: expression or identier based on the type of the abstraction and parameter Question: How actual and formal parameters relate/communicate? Programming language design should answer Parameter passing mechanisms
Copy mechanisms (assignment based) Binding mechanisms Pass by name (substitution based)
Copy Mechanisms
Function and procedure abstractions, assignment between actual and formal parameter:
1 2 3
Copy In: On function call: Fpi Api Copy Out: On function return: Api Fpi Copy In-Out: On function call: Fpi Api , and On function return: Api Fpi
C only allows copy-in mechanism. This mechanism is also called as Pass by value.
int x =1 , y =2; void f ( int a , int b) { x += a +b; a ++; b= a /2; } int main () { f ( x , y ); p r i n t f ( " x :% d , y :% d \ n " ,x , y ); return 0; }
b 2 1
b 0 0
b 2 1
Based on binding of the formal parameter variable/identier to actual parameter value/identier. Only one entity (value, variable, type) exists with more than one names.
1
Constant binding: Formal parameter is constant during the function. The value is bound to actual parameter expression value. Functional languages including Haskell uses this mechanism. Variable binding: Formal parameter variable is bound to the actual parameter variable. Same memory area is shared by two variable references. Also known as pass by reference
The other type and entities (function, type, etc) are passed with similar mechanisms.
int x =1 , y =2; void f ( int a , int b) { x += a +b; a ++; b= a /2; } int main () { f ( x , y ); p r i n t f ( " x :% d , y :% d \ n " ,x , y ); return 0; }
Pass by name
Actual parameter syntax replaces each occurence of the formal parameter in the function body, then the function body evaluated. C macros works with a similar mechanism (by pre-processor) Mostly useful in theoretical analysis of PLs. Also known as Normal order evaluation Example (Haskell-like)
f x y = if ( x <12) then x * x + y * y + x else x + x * x
Evaluation:
if (false)
(3*12+7)+(3*12+7)*(3*12+7) (3*12+7)+43*(3*12+7)
1892
(12 steps)
Evaluation Order
Normal order evaluation is mathematically natural order of evaluation. Most of the PLs apply eager evaluation: Actual parameters are evaluated rst, then passed.
f (3*12+7) (24+16*3) f (36+7) (24+16*3) f 43 72 if (43<12) then 43*43+72*72+43 else 43+43*43 if (false) then ... 43+43*43 1892
(8 steps)
Consider g x y= if x>10 then y else x for g 2 (4/0) Side eects are repeated in NOE. ChurchRosser Property: If an expression can be evaluated at
all, it can be evaluated by consistently using normal-order evaluation. If an expression can be evaluated in several dierent orders (mixing eager and normal-order evaluation), then all of these evaluation orders yield the same result.
Haskell implements Lazy Evaluation order. Eager evaluation is faster than normal order evaluation but violates Church-Rosser Property. Lazy evaluation is as fast as eager evaluation but computes same results with normal order evaluation (unless there is a side eect) Lazy evaluation expands the expression as normal order evaluation however once it evaluates the formal parameter value other evaluations use previously found value:
f (3*12+7) (24+16*3) if (x:(3*12+7)<12) then x:(3*12+7)*x:(3*12+7)+y:(24+16*3)*y:(24+16*3)+x:(3*12+7) else x:(3*12+7)+x:(3*12+7)*x:(3*12+7) if (x:43<12) then x:43*x:43+y:(24+16*3)*y:(24+16*3)+x:43 else x:43+x:43*x:43 if (false) then ... x:43+x:43*x:43 x:43+1849 1892
(7 steps)
Correspondence Principle
Correspondence Principle: For each form of declaration there exists a corresponding parameter mechanism. C: int a=p; void f(int a) { const int a=p; void f(const int a) { Pascal: var a: integer; procedure f(a:integer) begin const a:5; ??? { ??? procedure f(var a:integer) begin C++: int a=p; void f(int a) { const int a=p; void f(const int a) { int &a=p; void f(int &a) {