1
Lecture 1: Introduction to Oz Programming Language
Per Brand
2
Features of Oz
Oz is an object-oriented language, it provides state, abstract data types, classes, objects, and inheritance.
Oz provides the features of functional programming: a compositional syntax, first-class procedures, and lexical scoping. In fact, every Oz entity is first class, including procedures, threads, classes, methods, and objects.
Oz is a concurrent (constraint) language
users can create dynamically any number of sequential threads that can interact with each other.
executing a statement in Oz proceeds only when all real dataflow dependencies on the variables involved are resolved.
Oz is a (concurrent) logic programming language
3
Multi-paradigm
• Object-oriented, functional, constraint programming paradigms in one package
• Is this really possible ??– Can I easily achieve in Oz all that I can in my single-paradigm language
X??
– To a large degree yes
• dynamically typed though
– Cross-paradigm advantages also
• Doesn’t this multi-paradigm make a big mess ??– Well-integrated
– Simple kernel language
• higher-order makes the kernel simpler than most single paradigm languages
4
Example: Object-oriented
declare
class Counter %% class definition
attr count
meth init %% constructor method
count<-0 %% attribute update
end
meth inc %% public method (returning void)
count<-@count +1 %% attribute access by @
end
meth get($) %% public method (returning value)
@count %% implicit return
end
end
Obj={New Counter init} %% object constructed
{Obj inc} %% object used
{Obj inc}
{Show {Obj get($)}} %% we expect to see ‘2’
5
Observations
• Syntax– keyword rather than special character approach
• not enough special characters for all paradigms
• No types– Oz is dynamically typed
• What would happen on {Obj dec} ?
• Where’s the distinction with public/private/protected etc?.– All methods in the example are public– Later we show how to achieve private/protected in language security model
• Method of returning values look strange– Oz uses a more general concept than functions/object invocations return
values
6
Example: Functional
declare
fun{Double X} %% function definition
2 * X
end
fun{Map F L} %% parameter F is a function
case L of X|Xs then
{F X}|{Map F Xs} %% returns list
[] nil then
nil
end
{Show {Map Double [1 2 3 4]}} %% we expect to see ‘[2 4 6 8]’
%% Alternatively using anonymous function (lambda expression)
{Show {Map fun{$ X} 2*X end [1 2 3 4]}}
7
Example: Concurrent Constraint Programming
declare X A %% X and A are created unconstrained
thread %% thread created
case X of [_] then %% thread waits on data-flow
{Show triggered1(X)}
end
end
thread
case X of [1] then %% thread waits on data-flow
{Show triggered2(X)}
end
end
{Delay 100}
X=[A] %% X = [_] only first thread woken
{Delay 100}
A=1 %% X = [1] second thread woken
%% we expect to see ‘triggered1([_])’ before ‘triggered2([1])’
8
Observations
• Concurrency more and more important for networked applications.
• With concurrency (threads) you need to synchronize
• Two methods
– locking (monitors, sentinels etc.) • blocks other threads
• threads woken by unlocking (or notify)
• natural method when dealing with atomicity in continually changing composite stateful data e.g. critical region in object method application
– data-flow• threads blocked on data availability
• simpler and more efficient (data vs lock and data)
• requires monotonicity
– i.e. after thread becomes runnable always runnable, though the thread may suspend later after activation
9
Concurrent Constraint Programming
• Also gives powerful techniques for combinatorial search problems
• Not covered in this course (www.mozart-oz.org)– see Chapter 12 of Oz-Tutorial
– see Finite Domain Constraint Programming Tutorial
– see Part I in Demo Applications
10
How Oz will be presented
• Non-stateful non-concurrent subset • Oz without stateful entities, e.g. objects
– Stateless data structures
– Single-assignment variables
– Procedures
• Practical programming – OPI - open programming interface
– Mozart web site
• Concurrency and State– Threads and data-flow synchronization – Objects
– Ports (for message sending)
• Kernel Oz
• Practical programming– Libraries
– Debugger and other tools
11
Numbers
• Oz supports integers and floats
• Integers have infinite precision
• Characters are integers in the range 0..255 with syntactic support
– e.g. &t represents the character ‘t’
• Floats are different from integers and must have decimal points.
• Other examples of floats are shown where ‘~’ is unary minus: ~3.141 4.5E3 ~12.0e~2
• .
12
Literals
• Literals are divided into atoms and names.
• An atom is symbolic entity that has an identity made up of a sequence of alphanumeric characters starting with a lower case letter, or arbitrary printable characters enclosed in quotes.
• Example:
– a foo '=' ':=' 'OZ 2.0' – 'Hello World'
• Atoms have an ordering based on lexicographic ordering.
• Another category of elementary entities is name.
• The only way to create a name is by calling the procedure:
– {NewName X} • X is assigned a new name that is guaranteed to be worldwide unique
13
Boolean and Unit
• A subtype of name is bool.
• Consists of two names protected from being redefined by having the reserved keywords true and false.
• There is also the type unit that consists of the single name unit.
– This is used as synchronization token in many concurrent programs.
local X Y B in X = foo {NewName Y} B = true {Show [X Y B]}end
14
Records
Records are structured compound entities.
A record has a label and a fixed number of components or arguments.
There are also records with a variable number of arguments that are called open records.
– Example:
tree(key: I value: Y left: LT right: RT)
It has four arguments.
The label tree.
Each argument consists of a pair Feature:Field.
The features of the record is key, value, left, and right.
The corresponding fields are I, Y, LT, and RT.
15
Tuples
• It is possible to omit the features of a record.
• In Oz, this is called a tuple.
• Example:
– The following tuple has the same label and fields as the record shown before:
– tree(I Y LT RT)– It is just a syntactic notation for the record:
– tree(1:I 2:Y 3:LT 4:RT)
16
Lists
• The category of lists does not belong to a single data type in Oz. They are rather conceptual structure.
• A list is:
– either the atom nil representing the empty list, or
– is a tuple using the infix operator ´|´ and two arguments which are respectively the head and the tail of the list.
1|2|3|nil
• Another convenient special notation for a closed list, i.e. list with determined number of elements is:
[1 2 3]
• One can also use the standard notation for lists:
'|'(1 '|'(2 nil))
17
Infix Operator ´#´
• Another convenience is the infix operator ´#´.
• Used to anonymously group terms
a#b b#c#d
• One can also use the standard notation :
’#'(a b)
’#'(a b c)
18
Operations on Records - 1
• To select a field of a record component, we use the infix operator ‘.’
local X Y in
X = person(first:per last:brand)Y = person(per brand)
{Show X.first} %% shows per
{Show Y.2} %% shows brand
end
19
Operations on Records - 2
• The arity of a record is a list of the features of the record sorted lexicographically.
local X Y in
X = person(last:brand first:per )Y = person(per brand)
{Show {Arity X}} %% shows [first last]
{Show {Arity Y}} %% shows [1 2]
{Show {Label X}} %% shows person
end
20
Strings
• Strings are not a primitive type
• Further notational variant is allowed for lists whose elements correspond to character codes. Lists written in this notation are called strings, e.g.
– "OZ 2.0"
• is the list
– [79 90 32 50 46 48]
• or equivalently – [&O &Z & &2 &. &0]
21
Virtual Strings
• A virtual string is special a tuple that represents a string with virtual concatenation.
• Virtual strings are used for I/O with files, sockets, and windows.
• All atoms, except nil and #, numbers, strings, and #-labeled tuples can be used to compose virtual strings:
123#"-"#23#" is "#100
• represents the string
"123-23 is 100"
22
Variable Declaration
• In Oz computations are performed by a number of sequential threads.
• Threads have access to a shared memory called the store.
• Threads manipulate the store by reading, and adding information
• Information is accessed through the notion of variables.
• Oz variables are single-assignment variables.
• A single assignment variable:
Initially it is introduced with unknown value, unbound
Later it might be assigned a value, in which case the variable becomes bound.
• Once a variable is bound, it cannot be changed
23
Variable Introduction
A thread executing the statement:local X Y Z in S end
• Introduces three single assignment variables.
• Executes S in the scope of these variables.
Another form of declaration is:declare X Y Z in S
• Makes X Y and Z visible globally in S,and all statements the follows S textually in the session (file)
• Unless overridden again by another variable declaration of the same textual variables.
24
Binding a Variable
local P F N A in
P = person(fname:F lname:N add:A)
F = per
N = brand
local T N in
A = ’SICS’(town:T nat:N)
T = kista
N = sweden
end
end
Store
P
F
A
N
4 unbound variables
25
Binding a Variable-2
local P F N A in
P = person(fname:F lname:N add:A)
F = per
N = brand
local T N in
A = ’SICS’(town:F nat:N)
T = kista
C = sweden
end
end
Store
P
F
N
A
person
fname
lname
add
The record shows itself as a graph in the store
Store
26
Binding a Variable-3
local P F N A in
P = person(fname:F lname:N add:A)
F = per
N = brand
local T N in
A = ’SICS’(town:T nat:N)
T = kista
N = sweden
end
end
The outer variable N is no longer visibleLexical scoping
Store
P
F
T
A
person
fname
lname
add
Store
per
brand
SICS
town
nat
N
27
Binding a Variable-4
local P F N A in
P = person(fname:F lname:N add:A)
F = per
N = brand
local T N in
A = ’SICS’(town:T nat:N)
T = kista
N = sweden
end
end
The inner variables T N are no longer visibleThe outer variable N is again visible
What happens after the next end -what is visible then??
Store
P
F
A
person
fname
lname
add
Store
per
brand
SICS
town
nat
N
kista sweden
28
Equality operator - 1
• The equality infix operator =
X = 1
• Binds the unbound variable X to the integer 1.
• Add this information to the store.
• If X is already assigned the value 1, the operation is a no-op
• If X is already bound to an incompatible value, a proper exception will be raised.
local X in
X=1
X=1 % no-op
end
local X in
X=1
X=2 % exception
end
29
Equality operator - 2
• X=Y when X and Y are both unbound
• Binds the variables X and Y to each other, unifies them.
• Add this information to the store.
• If X is assigned the value 1, then Y is also bound to 1.
• Show will show 1#1.
local X Y in
X=Y
X=1
{Show X#Y}
end
local X in
X=1
X=2 % exception
end
30
Equality operator - over structures
• X=Y
• X and Y are unified or mutually constrained
• Adds the minimal information to the store to make X and Y equal
local X Y A B in
X=f(A b)
Y=f(a B)
end
X Y
f f
b a
X Y
f f
b aa b
31
Equality operator - over structures
• X=Y
• If X and Y are non-unifiable or incompatible a proper exception will be raised.
• The exception is called Tell failure:
– from constraint view we are trying to tell (add) a constraint to the store that would make it inconsistent
– in the constraint view there are only two things you do with the store
• tell
• ask
local X Y A B in
X=f(A b)
Y=f(a c) %% raises
%% exception
end
32
Anonymous variables
• The syntax _ can be used for creating a single-assignment variable without a handle.
• Even without a handle the single-assignment variable can be bound indirectly.
local X in
X=f(_ _)
{Show X} %% shows X=f(_ _)
X=f(a _) %% shows X=f(a _)
X=f(a b) %% shows X=f(a b)
end
33
Equality Test Operator ==
• The equality test operator == is the ask partner of the tell equality operator =
• The thread executing cannot know the result of the test Y==1 and waits until it can be decided.
• Later we shall see how useful this is
local X Y in
X=1
{Show X==1} %% shows true
{Show X==2} %% shows false
{Show X==f(a b) %% shows false
{Show Y==1} %% doesn’t show anything
end
34
Data Types with Structural Equality
• The data types we have introduced so far, records, integers, floats, etc. have structural equality
• 5 == 5.0 evaluates to false - floats and integers never equal
• f(A B)==f(C D) evaluates to true iff A==B and C==D are true
local X Y in
{Show f(a b)==f(a b)} %% shows true
{Show f(a b)==f(a c)} %% shows false
{Show f(a b)==f(c d)) %% shows false
{Show f(a _)==f(a b)} %% suspends!!!
end