D7020E
1
Robust and Energy-EfficientReal-Time Systems
D7020E
Lecture 2:Components & the Timber language
1
D7020E
Recall
2
Time
blocked
T
T
??
buffered
synchronouscall
asynchronous calls
... with offsetThe dynamic evolution of a system
2
D7020E
Also recall
3
The static structure of a system
The blocks look like components in an electronic circuit diagram...
??
3
D7020E
Components... A frequently used term in software engineering
Not always well-defined...
Still a very appealing engineering concept(c.f. electronic components)
Many similarities to objects:• Data encapsulation• Functional encapsulation• Access via interfaces only
However, the essence of components usually means• Context-independence – resuability – mass production!
4
4
D7020E
A source of confusion
Objects are unique run-time instances, they can't be reused• A component must mean a class instead...
However, classes usually refer to other classes and definitions in scope, can't be used outside their context• Maybe a component should mean a module...
But modules usually contain global state variables – should these be duplicated or not when components are mass-produced?• So a module is just like a fancy object?
5
5
D7020E
More confusion
How is concurrent execution related to components?Is a component equivalent to a thread?
What is the functional interface to a component?A set of procedures? What about synchronization?
What about underlying OS dependencies?
Can components be distributed? (Well, they ought to!)Then what is the protocol? Remote-procedure-calls?
How are component interfaces specified? What kind of types are allowed? Behavior specifications? Logic?
Should timing properties be part of an interface?
6
6
D7020E
Enter Timber (timber-lang.org)
A high-level programming language, built around the same programming model as TinyTimber:
Event-triggered execution =the classic object-oriented paradigm revisited!
In addition:• Dynamic object creation• Garbage-collecting memory management• Strong static type system including subtyping,
parametric polymorphism, dynamic overloading, ...• Rich assortment of immutable & higher-order data
7
7
D7020E
Timber and components
A split view:• When we engineer systems we think of components
as objects – unique instances each with a private state• What we really mean, though, are classes and not
objects, and that's what we write as program code• However, when it comes to reusability and mass-
production, a Timber component is a module:• Definitions of classes, functions and other constants
• Definitions of types
• But no mutable variables – modules can be freely duplicated, shared, reused, cached, packaged as binaries...!
8
8
D7020E
No declared global state!
State variables only exist within objects
And only classes (i.e., object generators) written in code
Classes may instantiate other classes, but only when they become instantiated themselves
Q: So how does this process start? Where is the root of the whole program instantiated?
A: In the run-time system, on basis of a class name given as an argument to the compiler (default: root)
• C.f. "Where does the function call-chain start in C? –In the run-time system, based on a name convention"
9
9
D7020E
Timber code vs. Timber at run-time
10
module A where
map f [] = []map f (x:xs) = f x : map f xs
id x = x
module B module D
module E where
myApp arg = class ...
module F
module C
module G where
aaa = 123
module H where
counter = class val := 0
inc = action val := val + 1
read = request result val
result Counter {..}
module I module J
module K where
anotherApp env = class
root = E.myApp
root = E.myApp
root = K.anotherApp
ImmutablereusableTimbermodules
MutableuniqueTimber"worlds"
10
D7020E
Local state
Run-time execution model
11
In parallelMutuallyexclusive
Object A
Object B
Method 4
Method 3Externalevents
Externalreactions
Asynchronous delayed
Asynchronous
Synchronous
Messages
↪
Local state
Method 2
Method 1
11
D7020E
Methods
12
Finite sequences that
• Read and write local state
• Call other methods
• Create new objects
• Perform pure computations
No indefinitely blocking operations,no infinite loops:
objects sleep between temporary activity
The classical OO intuition recast to a concurrent setting!
Local state
Method
Method
12
D7020E
A simple event counter
13
counter = class val := 0 inc = action val := val + 1 read = request result val result Counter { inc = inc, read = read }
asynchronous method
synchronous method
an object generator
local state
counter :: Class Counter
automatically inferred type
struct Counter where inc :: Action read :: Request Int
interface spec
struct stuffing
13
D7020E
A simple event counter
14
inc
read
val :: Int
↪
14
D7020E
Using the simple event counter
Somewhere in the code:
...c = new counter...c.inc...c.inc...v <- c.readif v == 2 then ...
15
object creation
asynchronous method call
synchronous method call, binds result to v
15
D7020E
Variant: a buffer
16
struct Buffer a whereinsert :: a -> Actionread :: Request [a]
buffer = classval := []insert x = action val := x : valread = request result valresult Buffer {..}
A type parameter
Listconstruction
Method takingan argument
insert
read
val :: [a]
↪
List type
16
D7020E
An extended buffer class
17
struct CBuffer a < Buffer a whereclear :: Action
buffer2 = classval := []insert x = action
val := x : valread = request result valclear = action val := []result CBuffer {..}
Declared subtyping (type extension)
insert
read
val :: [a]
↪
clear
17
D7020E
Alternative: a flush buffer
18
struct FlushBuf a whereinsert :: a -> Actionflush :: Action
fbuf consumer = classval := []insert x = action val := x : valflush = action consumer val val := []result FlushBuf {..}A required interface
fbuf :: ([a]->Action) -> Class (FlushBuf a)
insert
flush
val :: [a]
↪ ?
18
D7020E
In general
19
method1
methodN↪
...
↪
Required interfaceOften a struct... Often a struct...
Provided interface
19
D7020E
In general
20
method1
methodN↪
...
↪
Provided interfaces Required interfaces
Can also be (a tuple of) individual methodsOr any data structure containing methods!
20
D7020E
On data structures
All data are not objects!
In fact, Timber offers a wealth of immutable data:• Lists• User-defined structs• User-defined unions (tagged alternatives)• Tuples of any width• Arrays (become mutable when part of object state)• Functions (first-class citizens)• First-class methods, classes and commands
Objects only for capturing the state of a system
21
21
D7020E
Timber & Haskell As is syntactically obvious, Timber is a descendant of
Haskell (www.haskell.org)
Shares purely functional basis, strong typing principle, overloading system, many syntactic details
Differences in Timber:• Objects, methods & classes not part of Haskell
(which has a more traditional imperative top-level)• Event-triggered concurrency & timing• Standard strict expression evaluation
(as opposed to Haskell's lazy semantics)• Subtyping & user-defined structs
22
22
D7020E
Lists
Basic constructors:[] (the empty list) x:xs (x put in front of list xs)
Syntactic shorthand:[a,b,c,d] equivalent to a:b:c:d:[]
Analysis via pattern-matching & recursion:length [] = 0length (x:xs) = 1 + length xs
Concatenation (a standard operator):[] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)
23
23
D7020E
On syntax
Function calls don't need parentheses:length xs (call length with argument xs)sin (alpha+1.0) (call sin with argument alpha+1.0)min a b (call min with arguments a and b)
Operators are just infix functions with symbolic names:a + b (call + with arguments a and b)(a+b) * sin y (call * with arguments a+b and sin y)
Odinary calls always bind harder than operators
Operators have their "usual" precedence
Parentheses override any precedence
24
24
D7020E
User-defined structs
Introduced by declaration:struct Complex where re :: Float im :: Float
Makes Complex distinct from any other type
Constructing struct terms:Complex { re = 2.1, im = 5.0 }{ re = 2.1, im = 5.0 }
Accessing fields:x.re * x.re + x.im * x.im
25
Full form
When selectors identify the type
Also declares selectors re and im
25
D7020E
User-defined unions
Introduced by declaration:data Color = Red | Blue | Green
Construction (just say Blue, for example) and analysis:case x of Red -> 0 Blue -> 1 Green -> 2
Or, by means of a defined function:ff Red = 0ff Blue = 1ff Green = 2
26
26
D7020E
User-defined unions
Constructors with arguments:data IntOrBool = Itag Int | Btag Bool
Term construction is just application:Itag 87 or Itag 0 or Btag False
Analysis by pattern-matching:explain (Itag 0) = "zero"explain (Itag _) = "non-zero"explain (Btag True) = "true"explain (Btag False) = "false"
27
27
D7020E
Higher-order functions
Mapping a function onto a list of arguments:map f [] = []map f (x:xs) = f x : map f xs
Example of use:successor n = n + 1ys = map successor [1,2,3]
Alternatively, using an anonymous function:ys = map (\n -> n+1) [1,2,3]
28
28
D7020E
Overloading
Declaring overloaded equality operators:typeclass Eq a where (==),(/=) :: a -> a -> Bool
Making them defined for types Int and Char:instance eqInt :: Eq Int where (==) = primIntEQ (/=) = primIntNE
instance eqChar :: Eq Char where a == b = ord a == ord b a /= b = ord a /= ord b
29
29
D7020E
Polymorphic overloading
Open use of overloaded operators:elem x [] = Falseelem x (y:ys) = x == y || elem x ys
What would be a proper type for elem?elem :: Int -> [Int] -> Bool Too specificelem :: Char -> [Char] -> Bool Too specificelem :: a -> [a] -> Bool Too general
Solution borrowed from Haskell: add a class constraint!elem :: a -> [a] -> Bool \\ Eq a
(Note deviation from Haskell syntax, though)
30
30
D7020E
Pure computations
Compare f1 x = g x + g xwith f2 x = let y = g x in y + y
In Timber, f1 and f2 are provably identical, for all g!
In C, they would be different if g contains effects:int g (int v) { printf("Hello!"); return v*v; }
Timber distinguishes between effects and pure computations by means of types:
Int -> Int Pure functions from Int to IntInt -> Request Int Methods from Int to Int
31
31
D7020E
Commands
Timber has four forms of bindings/assignments:
x = exp x is defined equal to the value of exp
x = new exp x is defined equal to the result of instantiating class expression exp
x <- exp x is defined equal to the result of executing method expression exp
x := exp x is modified to become equal to exp (x must be a state variable in scope)
Only the first two forms may be recursive Form x <- exp may not occur in class bodies
32
32
D7020E
Examples
Simple value bindings:incBy4 = \v -> v+4seven = incBy4 3
Syntactic short-hand for function values:incBy4 v = v+4
Non-recursive mutation of state variable s:s := incBy4 s
Mutually recursive object instances:a = new classA bb = new classB a
33
33
D7020E
Easy mistakes
Unintended recursive binding (rejected):meth x = action x = incBy4 x(Solution: call local variable something else than x!)
Confusing a method with its result:x = obj.meth argy = x + x(Solution: write x <- obj.meth arg to capture result!)
Use of instantiation as an expression:x = f (new myClass)(Solution: write y = new myClass as a separate binding)
34
34
D7020E
A sonar example
35
echo
ping
stop
reset
sample
↪
↪
↪
↪
alarm
portstart
interrupt
35
D7020E
A sonar examplesonar port alarm critical = class tm = new timer count := 0 ping = action port.write beepOn tm.reset after (millisec 2) stop after (sec 3) ping stop = action port.write beepOff echo = action diff <- tm.sample if critical diff then count := count + 1 alarm count result { interrupt = echo, start = ping }
36
A local object A built-in class for measuring time
Returns time since last reset
A function parameter
36
D7020E
The sonar program root
37
alarm↪
regs
inte
rrup
ts
↪
↪sonar
37
D7020E
The sonar program root
root regs = class crit d = d < millisec 15 a = new alarm (regs ! comPortAddr) s = new sonar (regs ! sonarPortAddr) a crit result [ s.start, s.interrupt, a.ack ]
38
The required interface (Here: an array of ports)
The provided interface (Here: a list of interrupt handlers)
A boolean function passed as a parameter
38
D7020E
The root under POSIX
root env = class a = new b ... ... result action ... env.stdin.installR a.keyHandler ...
39
The required interface (Here: a struct of OS services)
The provided interface (Here: just a startup method ≈ main)
39