Basic
Language evaluation criteria
Types and values
Functions and variables
Syntax
Memory management
Evaluation criteria
Readability
- simplicity, orthogonality 1 fast learning curve
Writability
- expressivity
- polymorphism
Reliability
- compile-time checking
- readability
Types and values (1)
Programming = manipulating values
Builtin values: 1, 1.1, 'z'
Low-level types:
- char, short, int, float, double, pointers
- based on hardware representation
Higher-level types: lists, arrays
Types and values (2)
User defined:
- structs: point = { x: int; y: int }
- enums, ranges: bool = { false, true }
- datatypes: tree(a) = leaf(a) | node(tree(a),tree(a))
Subtyping
- 3dpoint = { x: int; y: int; z: int }
- can be used when a point (see above) is expected
Abstract types
Functions
Functions
- Mathematical meaning: parameters µ result
- When parameters are evaluated?
- when used: lazy evaluation (haskell, eg: if)
- when function is called: strict evaluation
First class values = can be given as argument & result
- arrays nor functions are first class in Pascal
Functions (2)
Parameter passing mode
- in vs out vs inout
- out was used
- to return multiple values
- let the caller allocate memory
- out deprecated by GCs and lists as first class values
Purity:
- The function must not depend nor modify a global state.
- consequence: same parameters 1 same result
- eg: printf, ++ are unpure functions
Functions (3)
Extensions:
- Arguments
- variable number of arguments
- named arguments
- Non stack based: continuations
- closure, backtracking, constraints, exceptions
Syntax: orthogonality
orthogonality = universality, no special case to know (least surprise)
more orthogonality means
- faster learning curve
- easier maintenance
examples of non-orthogonality
- C's macros: language in the language
- C's comments: can't be nested
- Perl's horrors
- () used for grouping and lists and function calling
- eg: ("Hello " . $name) x 2
- filehandles
- $_ used as default value in some functions (esp. split ' ')
- {} used for blocks and hashes
- if-then-else returns a value but is not an expression
Syntax: terseness
Use of words (begin, def...)
Operator overloading (semantic!)
Special terse construct
- Perl!
- -> optional sometimes
- => allow removing quotes on its left
- quoting: ' " ` q qw qq...
- || vs or vs unless, && vs and vs if
- list comprehension, pattern matching, case statement
- !! Importance of good error messages
Syntax: scope
block structure enables local definitions (variables and sometimes functions)
lifetime is limited to the block 1 ease maintenance & readability
indentation based block structure: follows WYSIHIIP (What You See Is How It Is Parsed)
namespaces
- can you have a type with a same name as a variable?
- if so types and variables have different namespaces
Syntax: statements
Expressions vs statements
- a statement is like a procedure, it doesn't return any value
- i=0 being a statement disallows: j=(i=0), if (i=0) ...
- ML enforces via types what Python does via syntax
Memory management
- Static: everything must be known at compile time
- Stack:
- enables recursion
- enables stack allocated arrays (growing data)
- Heap:
- pros: data can outlive function
- cons: need to free memory
- GC (Garbage Collector)
- Heap with no need to free memory by hand
Memory management: GC
- pros:
- allows implicit memory allocation
- allows mutable lists in the language, eg: l = [1,2]
- favours data sharing, can be more efficient than hand-managed memory
- cons
- can be slow
- finalization time is unknown
implementation
- reference counting (incremental, but circular ref!)
- mark & sweep (can be incremental)
- copying
- generational (mixed of copying and mark&sweep)
Memory management: Data sharing
shallow vs deep copy
shallow vs deep comparison
no such problem with purely functional data structures
- shallow and deep is the same
- because use of copy on write
Pointers are dead!
Datatype created in PL/I to access memory a la assembly
Pros: liberty, powerful
Cons:
- unsafe
- don't get along with GC
- char* is not a good representation of strings
- (see perl where substr is seldom used)
- arrays need a proper API
Replaced by references
- no arithmetic operation allowed
- only dereferencing
Advanced Programming
Typing
Functional programming
Programming howto
Modules
Type classes
Polymorphism
Classes, inheritance
Performance
Typing (1)
Static explicit classical typing (since Algol)
- pros: tight checking, simple
- cons: verbose (esp. for iteration variables)
Dynamic
- pros:
- flexibility, expressivity (remove/create function/method at runtime)
- cons:
- nearly no verification at compile-time (-Wall, use strict usually available but half-baked solutions)
- runtime cost
Typing (2)
Implicit static (invented in ML, 1977)
- find out variable and function types based on their use, eg:
- fact(x)= if x=0 then 1 else x*fact(x-1)
- x compared with 0 implies x is a int
- fact can return 1 implies fact returns a int
- This inference works nicely with complex programs
- pros:
- as good type checking as explicit static
- most of the expressivity of dynamic typing
- cons: sometimes type error messages don't occur where you would except
Functional programming
List handling (now available in dynamic languages)
Partial application
- map (round 0.01) [ 1.333, 4 ]
Closure (now available in many languages)
- b1 = Gtk::Button.new("One")
- b2 = Gtk::Button.new("Two")
- b1.signal_connect(clicked => sub {
- })
- Without closures, b2 should passed as a parameter (via void* ?) or via a global/class variable
Programming howto (1)
You have a task to do
- bottom-up
- you know how to achieve small tasks
- you build the whole program from these parts
- Used when specifications are foggy
Programming howto (2)
- top-down
- you split the problem into parts
- until those parts are simple enough
- Used when specifications are well established
A mix of bottom-up and top-down is usually used
1 Importance of modularity
- ease group-working and code reuse
Modules
Separate namespaces
- for types, variables, functions
- avoid the need for prefixed names (eg: gtk_...)
- avoid the need to prefix inside the module
Facilities to import/export names
- the module can choose what is exported
- ability to choose what to import
- possibility to alias/rename when importing
1 avoid name clashes
1 provide abstraction via information hiding (encapsulation)
Type classes (mix-ins)
Type class = special kind of module
- some functions are virtual
- specify the type of those functions (for static typing)
- 1 ensure a common behaviour
- write other functions using those virtual functions
Example:
- class Eq(a) where
- == :: a,a -> bool
- x!=y = ! (x==y)
- (this type is parametric, more about it in next slide)
Polymorphism
Coercion polymorphism
- up-cast parameter (eg: int i = 1; sqr(i))
Overloading polymorphism
- same function name with different parameter types. eg: print(int) and print(char *)
Parametric polymorphism
- Parametric functions
- ML: sort :: (a,a->int), list(a) -> list(a)
- C++: template<class A>
- vector<A> sort(vector<A>, int (*)(A,A))
- Parametric type classes
- Parametric classes (more about classes in next slide)
Classes
A class is a type
- you can instanciate it, you get an object
- it defines a data type (usually a struct)
- it defines a collection of functions(called methods) an object have
1 object = first class anonymous module
Inheritance
importing another class (inheriting) implies subtyping (not so with mix-ins which are not types)
- here an object Square can be used as an object Figure
- when calling a method on a object Figure, it can in fact be a Square, a Circle or ...
- 1 the good method to call can only be chosen at runtime (late binding)
Performance
www .bagley.org/~doug/shootout
C++ 76
OCaml 76
Java 69
CommonLisp 55
Perl 53
Python 46
Ruby 44
!! benchmarks are dangerous and show only some use !!