230 likes | 312 Views
Values and Types. Types of values. Primitive, composite , recursive types. Type systems: static vs dynamic typing, type completeness. Expressions Functions Conditional expressions Arrays Implementation notes. What is the difference between expression and statement in programming?.
E N D
Values and Types • Types of values. • Primitive, composite, recursive types. • Type systems: static vs dynamic typing, type completeness. • Expressions • Functions • Conditional expressions • Arrays • Implementation notes.
What is the difference between expression and statement in programming? • A statement is a complete line of code that performs some action • An expression is any section of the code that evaluates to a value • If you can print it, or assign it to a variable, it’s an expression. If you can’t, it’s a statement! • How about print in Python2 vs Python3?
Statement vs Expressions in Python • Statements: • import os • assert True • pass • del x • try: • raise Exception() • except: • pass • with open(‘/dev/null’) as fd: • pass • Expressions • Values are expressions • print(10+2) • print(‘a’) • Function calls are expressions • print(print(10)) • List comprehensions are expressions • Print([x*2 for x in range(2)])
Function calls • An operator may be thought of as denoting a function. • Applying a unary operator Å to its operand is essentially a function call with one argument: ÅEis essentially equivalent to Å(E) • Applying a binary operator Ä to its operands is essentially a function call with two arguments: E1ÄE2is essentially equivalent to Ä(E1, E2) • Thus a conventional arithmetic expression is essentially equivalent to a composition of function calls: a * b + c / d is essentially equivalent to => infix notation+(*(a, b), /(c, d)) => prefix notation
Conditional expressions chooses one of its subexpressions to evaluate, depending on a condition. • An if-expression chooses from two subexpressions, using a boolean condition. • A case-expression chooses from several subexpressions
Example: Java if-expressions • Java if-expression: x>y ? x : y • Conditional expressions tend to be more elegant than conditional commands. Compare: int max1 (int x, int y) {return (x>y ? x : y);} int max2 (int x, int y) {if (x>y)return x;elsereturn y;}
Example: Haskell if- and case-expressions • Haskell if-expression: if x>y then x else y • Haskell case-expression: case m of feb -> if isLeap y then 29 else 28 apr -> 30 jun -> 30 sep -> 30 nov -> 30 _ -> 31
Iterative expressions • An iterative expression • performs a computation over a series of values (typically the components of an array or list), yielding some result. • Iterative expressions are uncommon • but they are supported by Perl by grep
Example: Perl iterative expressions via grep #!/usr/bin/perl use strict; use warnings; my %data = ("A" => 0, "B" => "yes", "C" => 0 ); my @arrkeys = grep { $data{$_} } keys %data; • keys %data returns a list of characters (“A”,”B”,”C”) • { $data{$_} } runs once for each character , and returns (0,”yes”,0) • grep returns only the values from the list on the right-hand side for which the expression in braces evaluates to a true value.
y 2000 2004 m jan dec d 1 25 Implementation Details:Representation of Cartesian products • Tuples, records, and structures are represented by juxtaposing the components in a fixed order. • Example (C++): struct Date{ int y; Month m; int d;}; • Implementation of component selection: • Let r be a record or structure. • Each component r.f has a fixed offset (determined by the compiler) relative to the base address of r.
3.0 1.0 1 4.0 1.0 2 0.0 0.5 3 Representation of arrays (1) • The values of an array type are represented by juxtaposing the components in ascending order of indices. • Example (C++): typedeffloat Vector[3];
Representation of arrays (2) • Implementation of array indexing: • Let a be an array with index range {l, …, u}. • Assume that each component occupies s bytes (determined by the compiler). • Then a(i) has offset s(i–l) bytes relative to the base address of a.(In C and Java l = 0, so this simplifies to si bytes.) • The offset computation must be done at run-time (since the value of i is not known until run-time). • A range check must also be done at run-time, to ensure thatliu.
Inexact tag Exact tag variant 2 variant 3.1416 Representation of disjoint unions (1) • Each value of a disjoint-union type is represented by juxtaposing a tag with one of the possible variants. The type (and therefore representation) of the variant depends on the current value of the tag. • Example (Haskell): data Number = Exact Int | Inexact Float
acc exact acc inexact ival 2 3.1416 rval Representation of disjoint unions (2) • Example (C++): typedefenum{exact, inexact } Accuracy ; typedefunionNumber{ intival; floatrval; }Number; typedefstructDataNode { Accuracyacc; Numberrval; }DataNode;
Point tag 1.0 x Circle tag 2.0 y 0.0 x Rect. tag 0.0 y 1.5 x 5.0 r 2.0 y 3.0 w 4.0 h Representation of objects (simplified) • Example (Java): class Point {privatefloat x, y;… // methods} class Circleextends Point {privatefloat r;… // methods} class Rectangleextends Point {privatefloat w, h;… // methods}
Representation of disjoint unions (3) • Implementation of tag test and projection: • Let u be a disjoint-union value/object. • The tag of u has an offset of 0 relative to the base of u. • Each variant of u has a fixed offset (determined by the compiler) relative to the base of u.
Variables and Storage ‘‘Once a programmer has understood the use of variables, he has understood the essence of programming.’’ by Edsger Dijkstra
Variables and Storage • A simple storage model. • Simple and composite variables. • Copy semantics vs reference semantics. • Lifetime. • Pointers. • Commands. • Expressions with side effects. • Implementation notes.
An abstract model of storage (1) • In functional and logic PLs, a “variable” stands for a fixed but unknown value. • In imperative and OO PLs, a variable is a container for a value, which may be inspected and updated as often as desired. • Such a variable can be used to model a real-world object whose state changes over time.
unallocated unallocated cells 7 allocated allocated allocated cells true 3.14 ? ‘X’ An abstract model of storage (2) • To understand such variables, assume a simple abstract model of storage: • A store is a collection of storage cells. Each storage cell has a unique address. • Each storage cell is either allocated or unallocated. • Each allocated storage cell contains either a simple value or undefined. undefined
Variables and Storage • A simple storage model. • Simpleand composite variables. • Copy semantics vs reference semantics. • Lifetime. • Pointers.
Simple vs composite variables • A simple value is one that can be stored in a single storage cell (typically a primitive value or a pointer). • A simple variable occupies a single allocated storage cell. • A composite variable occupies a group of allocated storage cells.
n ? n 0 n 1 Simple variables • When a simple variable is declared, a storage cell is allocated for it. • Assignment to the simple variable updates that storage cell. • At the end of the code block, that storage cell is deallocated. • Animation (C++): If (1 == 1 ){ int n; n = 0; n = n+1; }