[NAME]
ALL.dao.guide

[TITLE]
The Quick and Simple Guide

[DESCRIPTION]

This quick and simple guide will cover some basics of Dao programming.

 1   Basics     
 1   Basics     
 1   Basics     


We will start with the traditional hello world example.

 1.1   Hello World!  

To simply write "Hello world!" to the screen, one can use, 
     
   1  io.write( "Hello world!" )
     
In this simple example, the built-in io module is used to access the IO functionalities o
f the module. write() is a method provided by the io module to write outputs on to the st
andard output (the screen in this case). In Dao, string can be quoted with a pair of sing
le quotation marks or with a pair of double quotation marks. Semicolons are optional at t
he end of statements.

 1.2   Running Scripts  

There are three ways to run codes in Dao. The most typical way is to create a script file
(e.g. hello_world.dao), and put the codes into this file, and then run dao using this fil
e as argument, 
     
   1  $$ dao hello_world.dao
     

But if you just want to run the codes once, you can simple run them from command line usi
ng, 
     
   1  $$ dao -e "io.write( 'Hello world!' )"
     

For learning Dao, it may be the best to run codes in interactive mode. Invoking dao witho
ut any argument will start an interactive shell, 
     
   1  $$ dao
   2  
   3    Dao Virtual Machine 2.0
   4    Built date: Jun 12 2014
   5    Changeset ID: FOS.4d5eb15f0e53
   6  
   7    Copyright(C) 2006-2014, Fu Limin
   8    Dao is released under the terms of the Simplified BSD License
   9    Dao Language website: http://www.daovm.net
  10  
  11  (dao)
     


 1.3   Accessing Online Help  

If you have the Dao help properly installed, starting dao in interactive mode will automa
tically load the help files and print out the following information, 
     
   1  Module Help is loaded.
   2    Now you may run "help()" to list all the available help entries;
   3    or run "help('help')" for detailed information about the help system.
     
If you are reading this tutorial from a webpage, and want to access it from the interacti
ve command line, you can simple run, 
     
   1  (dao) help( "dao.guide" )
     

Such online helps come in two languages: English and Chinese. To choose the language, 
     
   1  (dao) help::set_language("en");  # choose english;
   2  (dao) help::set_language("zh");  # choose chinese;
     


 1.4   Commenting Codes  

It is always a good idea to comment your codes. Dao supports both single line comments an
d multiple line comments. A single comment starts at a #  (not followed by a left curly b
racket {), and ends at the end of the current line. And a multiple line comment (or just 
part of a single line) opens by #{ and closes by #}. For example, 
     
   1  # This is a simple demo:
   2  io.write( "Hello World!" #{ comment inside codes #} );
   3  #{
   4  Here are multi-lines comments.
   5  Here are multi-lines comments.
   6  #}
     


 1.5   Constants, Variables and Invariables  

Dao supports the explicit declaration of constants, local variables, static variables, gl
obal variables and invariables. Constants are declared with keyword const, 
     
   1  const DEFAULT_INDEX = 123
   2  const DEFAULT_NAME  = 'abc'
     
Constants can only be initialized with constant expression. Constants that are declared a
t the top lexical scope are global constants.

Keyword var can be used to declare local and global variables. If used at the top lexical
scope, it will declare global variables, otherwise the declared variables will be local. 
     
   1  var current_index = 456    # global variable;
   2  var current_name  = 'def'  # global variable;
   3  if( current_index ) {
   4      var temp_index = current_index  # local variable;
   5  }
     

In every places where var can be used, invar can be used as well, to declare local, globa
l or member invariables. Invariables are special kind of variables that cannot be modifie
d once initialized. 
     
   1  var   varlist = { 123 }
   2  invar invlist = varlist
   3  
   4  invlist.append( 456 )  # Error!
     
Please see dao.data.invar for more information.

Another type of variable is the static variable which can be declared with the static key
word. Outside class body, a static variable is a global variable with strictly local visi
bility within its declaration scope. So if a routine with static variables is executed mu
ltiple times, all the executions will access the same static variables. Static variables 
must be initialized with constant expressions.

Without the above specifiers, newly declared symbols in the form of name=expression will 
be automatically declared as local variables.  But if the symbol was defined as variable,
such statements will simply reinitialize the existing variable. To avoid this, one must t
he keyword var to explicitly declare the variable as local, 
     
   1  var index = 789
   2  for( i = 1 : 3 ){
   3      var index = 123  # Local to the loop;
   4  }
     

Please read dao.data for more information.
Note: in interactve mode, all top level variables are automatically declared as global va
riables. 

 1.6   Type Annotation  

In the above examples, no type information is declared for the constants, variables and i
nvariables. Their types are automatically inferred from the values that were used to init
ialize them. In many cases, it is better to provide type annotations to the constant, var
iable and invariable declarations. In general, programs with good type annotations are mo
re readable them programs without them. It also makes error detection in such programs ea
sier.

Type annotations are usually placed after the constant/variable/invariable names with a c
olon sparating them. 
     
   1  const vector:  array<float> = [ 12.5, 34.6 ]
   2  invar invlist: list<float> = { 12.5, 34.6 }
   3  var   varlist: list<int>
     
Here without type annotation, "vector" will become a constant of type "array<float>". And
"varlist" is declared without initializing expression, so its type cannot be inferred her
e.

As you will see, type annotations can also be used in routine/function signatures and cla
ss member fields. Please read dao.type for more information.

 2   Data Types     
 2   Data Types     
 2   Data Types     

Dao supports a good number of data types to facilitate programming. These include, boolea
n type, several number types, enum symbol, string, numeric array, tuple, list and map etc
. types. 

 2.1   Boolean  

Boolean (bool) is a simple logical data type representing true and false. 
     
   1  B1 = true
   2  B2 = false
   3  B3 = 3 > 2
   4  B4 = B1 and B2
     


 2.2   Numbers  

Dao has native supports for the following number types: int, float, and complex. Both int 
and float are stored in 64 bits. Integer and floating point numbers can be expressed in t
he same ways as in most other languages. Number literals suffixed with C represent the im
aginary parts of double precision complex numbers.

Examples, 
     
   1  I1 = 123     # Base-10 integer;
   2  I2 = 0xabc   # Base-16 integer;
   3  F1 = 456.7   # Double precision;
   4  F2 = 123e4   # Double precision;
   5  F3 = 123E4   # Double precision;
   6  C1 = 123C    # Double precision complex number with 0.0 real part and 123 imag part;
   7  C2 = 456.6C  # Double precision complex number;
     

These types support most of the common operators that are meaningful for them. For exampl
e, all the basic arithmetic operators such as: + (addition, unary plus), - (subtraction, 
unary minus), * (multiplication) and / (division). are supported. 
     
   1  I1 = 123 + 456
   2  I2 = 789 % 123
   3  F1 = 123.5 ** 3
   4  F2 = 789.5 / 123
   5  C1 = 12.3 + 45.6C
     

Please see dao.type.int,  dao.type.float and  dao.type.complex for more information.

 2.3   Enum Symbols  

An enum defines a set of symbols with associated integer values. It is particularly usefu
l to represent states and flags. 
     
   1  enum MyEnum
   2  {
   3      AA    ,  # 0
   4      BB = 3,  # 3
   5      CC       # 4
   6  }
     
These symbols are not exposed to the current namespace. So they have to be accessed as fi
elds of the enum type, 
     
   1  a = MyEnum::AA  # Or: MyEnum.AA;
     


There is a special type of enum called symbol, which appears as an ordinary identifier pr
efixed with  a dollar sign $. Such symbols are often used in conjunction with normal enum
types. 
     
   1  enum E1 { AA=1, BB=2 }
   2  enum E2 { AA=10, BB=20 }
   3  
   4  var e1: E1 = $AA
   5  var e2: E2 = $AA
   6  
   7  io.writeln( e1 )  # Output: $AA(1)
   8  io.writeln( e2 )  # Output: $AA(10)
     
Here symbol "$AA" is assigned to both "e1" and "e2", and the symbol get interpreted prope
rly according the types of "e1" and "e2". So what a symbol represents actually depends on
the variable type to which is assigned.

Another way to use enum types is to use the enum type names: 
     
   1  var e1: enum<AA,BB> = $AA
   2  var e2: enum<AA=10,BB=20> = $BB
     

There are different types of enum types to support different operations. Please see dao.type.enum 
for more information.

 2.4   Strings  

A Dao string is simply a sequence of bytes, which can contain arbitrary data. But when pr
ocessed as text, it is usually assumed to be encoded in UTF-8. Strings can be expressed a
s string literals quoted with double or single quotation marks. 
     
   1  S1 = 'Something'
   2  S2 = "道语言"
   3  S3 = 'It\'s green'
   4  S4 = "\u9053\u8bed\u8a00" # the same as S2: "道语言";
     
Inside string lieterals, some characters need to be escaped with backslashes. Some others
such as \u are used to instruct Dao parser to interprete the following byte sequences spe
cially.

To use strings as it is written without special treatment of the characters, they can be 
expressed as verbatim string, which are quoted with a pair of identical compound marks in
the forms of @[]. Any number of letters, digits, underscores, blank spaces, dots,  colons
, dashes and assignment marks can be placed in between the squared brackets to make sure 
the marks will not appear inside the string. 
     
   1  # C++ codes as verbatim string:
   2  cpp =
   3  @[cpp x]
   4  class AA
   5  {
   6  	int index;
   7  };
   8  struct BB{};
   9  @[cpp x]
     

The content of a string can be accessed or altered using sub-indexing or slicing: 
     
   1  str = "ABCDEFGHIJK";
   2  
   3  io.writeln( str[1] )    # the second character;
   4  io.writeln( str[:4] )   # the substring from the start to the 4th character;
   5  io.writeln( str[6:] )   # the substring from the 6th character to the end;
   6  io.writeln( str[3:8] )  # the substring from the 3rd to the 8th character;
   7  
   8  str[1] = "X";        # Change a single byte: str = "AXCDEFGHIJK";
   9  str[2:5] = "123456"  # Change a substring: str = "AB123456GHIJK";
     

String can be concaternated using + or +=, 
     
   1  str = "ABCDEFGHIJK";
   2  
   3  str2 = str + "123"  # str2 = ABCDEFGHIJK123
   4  str += "123" # Append a string: str = ABCDEFGHIJK123
   5  str += 88    # Append a character: str = ABCDEFGHIJK123X
     

The string type supports a number of builtin methods for handling its data. Among these m
ethods, there are also string pattern matching methods. Please read dao.type.string for m
ore information.

 2.5   Numeric Arrays  

Dao has built-in support for multi-dimensional numeric arrays. Such arrays can be defined
by using the squared brackets [] or array{}. Using such constructs, one can either enumer
ate all the elements as a vector/matrix, or specify an arithmetic progression with a star
t value, a step value and the number of steps. If the step value is omitted, it will be a
ssumed to be zero.
     
   1  vec1 = [1, 2, 3]            # array<int> vector, or 1x3 matrix;
   2  vec2 = [1.0; 2; 3]          # array<float> 3x1 matrix, or transposed vector;
   3  mat1 = [1.0, 2; 3, 4]       # array<float> 2x2 matrix;
   4  mat2 = [ [1, 2], [3, 4] ]   # 2x2 matrix
   5  mat3 = array{ 1, 2; 3, 4 }  # 2x2 matrix
     

Like string, array support sub-indexing and slicing: 
     
   1  mat = [ 1, 2, 3; 4, 5, 6; 7, 8, 9 ];  # 3x3 matrix;
   2  
   3  rowvec = mat[1,:]  # the second row;
   4  colvec = mat[:,1]  # the second column;
   5  
   6  submat1 = mat[:1,:]  # the first two rows;
   7  submat2 = mat[:,1:]  # the last two columns;
   8  submat3 = mat[:1,1:] # intersection between the first two rows and the last two columns;
   9  
  10  mat[0,:]  = [11, 22, 33]  # set the first row to [11, 22, 33];
  11  mat[:,1] += [11, 22, 33]  # add [11, 22, 33] to the second column;
  12  mat[:,1] += 100           # add 100 to the second column;
  13  
  14  mat[:1,1:] += [10, 20; 30, 40]  # add [10, 20; 30, 40] to sub-matrix of mat;
     

Please see dao.type.array for more information.

 2.6   Lists  

List can be created in similar ways as array, by enumerating elements or specifying an ar
ithmetic progression, but using {} or list{} instead of [] or array{}.
     
   1  list1 = { 1, 2, 3 }    # list<int>
   2  list2 = { 1.0, 2, 3 }  # list<float>
   3  list3 = { 1 : 2 : 5 }  # list<int>
   4  
   5  list4 = { 'abc', 'def' }  # list<string>
   6  list5 = { 123, 'abc' }    # list<any>
     

List also supports sub-indexing and slicing: 
     
   1  alist = { 0, 1, 2, 3, 4, 5 }
   2  
   3  item = alist[1]
   4  sublist = alist[2:4]
   5  
   6  alist[3]  = 10
   7  alist[4] += 10
     


 2.7   Maps and Hash Maps (Associative Arrays)  

A map or hash map organizes a set of key/value pairs into a structure for efficient looku
p. The keys in a map are ordered, while the keys in a hash map are unordered.

A map can be created using {key=>value...} or map{key=>value...}. Replacing the => with c
olon -> will create hash maps. Map and hash map can be used in identical ways. 
     
   1  amap  = { 'abc' => 123, 'def' => 456 }
   2  ahash = { 'abc' -> 123, 'def' -> 456 }
   3  
   4  amap  = map{ 'abc' => 123, 'def' => 456 }
   5  ahash = map{ 'abc' -> 123, 'def' -> 456 }
     

Sub-scripting and slicing are also supported for map to access value(s) through key(s). 
     
   1  amap = { 'abc' => 123, 'def' => 456, 'ghi' => 789 }
   2  
   3  value  = amap[ 'abc' ];
   4  submap = amap[ 'abc' : 'def' ];
     


 2.8   Tuples  

Tuple is a data type that can store a fixed number of items with individual type annotati
on for each item. Each item may optionally have a field name. They can be created in simi
lar ways as creating lists and maps, but using () instead. 
     
   1  tup1 = ( 123, 'abc' )               # tuple with unnamed items;
   2  tup2 = ( index = 123, 'abc' )      # the first item is named as "index";
   3  tup3 = tuple{ 123, name = 'abc' }  # the second item is named as "name";
     

Each item of a tuple can be accessed using its index or field (item name). New tuples can
be created from other tuples by slicing. 
     
   1  tup = ( index = 123, 'abc', [1,2,3] )
   2  
   3  id = tup[0]
   4  id = tup.index
   5  tup.index = 456
   6  
   7  tup2 = tup[:1]  # ( index = 123, 'abc' )
     


 3   Control Constructs     
 3   Control Constructs     
 3   Control Constructs     

The logic of a program is mostly expressed with constrol constructs. Dao supports the com
monly used controls such as: if-else, for, while, do-while, switch-case,  break and skip 
etc.

 3.1   If-Else Conditional Construct  

The if-else control allows the program to branch and execute different blocks of codes, b
ased on the results of the condition expressions.

When the execution reachs an if-else block, the condition in the if() clause will be test
ed first, if the test is successful, the block associated with the if clause will be exec
ute. Otherwise the next else if() clauses (if any) will be tested one by one, until one s
ucceeds the test, then the block of the succeeded else if() clause will be executed. If n
one of the conditions suceeds and  there is an else clause, its block will be executed in
stead. 
     
   1  if( rand(10) > 7 ){
   2      io.writeln( "greater than 7" )
   3  }else if( rand(10) > 5 ){
   4      io.writeln( "greater than 5" )
   5  }else if( rand(10) > 3 ){
   6      io.writeln( "greater than 3" )
   7  }else{
   8      io.writeln( "not greater than 3" )
   9  }
     

Before each condition expression, there can be an optional expression or variable declara
tion, for example, 
     
   1  if( rnd = rand(100); rnd > 50 ) io.writeln( "random number:", rnd );
     


 3.2   For Looping Construct  

Dao supports three different styles of for loops: 
  *  For-in loop;
  *  Range for loop;
  *  C style for loop; 


For-in loop can normally used to iterate over the items of a container object. It is prob
ably most useful with list. 
     
   1  numbers = { 1, 2, 3, 4, 5 }
   2  for( num in numbers ) io.writeln( num )
     


A range for loop uses an arithmetic progression condition to control the loop. The arithm
etic progression condition usually consists of an initial value, an optional step value a
nd a stopping value. 
     
   1  for( index = 1 : 2 : 10 ) { # step value = 2;
   2      io.writeln( index )
   3  }
   4  for( index = 1 : 10 ) {  # step value = 1;
   5      io.writeln( index )
   6  }
     
The loops will start with "index=1", and with each loop cycle, "index" is increased by tw
o or one, when "index" become greater than 10, the loop will stop.

C-style for loop is the most flexible for loop construct. 
     
   1  for( init; condition; step ){
   2     block;
   3  }
     
The essential execution logic or steps of for statement is the following, 
  1. Execute the initial expression init;
  2. Check the condition expression condition;
  3. If true continue to the next step, otherwise exit the loop;
  4. Execute the code block block;
  5. Execute the step expression step and go to 2; 
The detailed steps may depends on the implementation but the basic execution logic is the
same.

Example, 
     
   1  for(i=0; i<3; ++i){
   2     io.writeln( i );
   3  }
     


 3.3   While Looping Construct  

while is a simple looping construct that executes a block if the looping condition is tru
e, and repeats the execution as long as the condition is true. 
     
   1  while( expression ){
   2     block;
   3  }
     
If expression is true, block is executed and repeated  until expression becomes false, na
mely, while expression is true, execute block.
     
   1  i = 0;
   2  while( i < 5 ){
   3     io.writeln( i );
   4     i += 1;
   5  }
     


 3.4   Do-While Looping Construct  

Do-while is a simple looping construct that executes a block and repeats the execution un
til its looping condition become false.
     
   1  do {
   2      block;
   3  } while ( condition )
     
Execute block, and then repeat executing it until the condition become false.

 3.5   Switch-Case Construct  

Switch-case control provides a convenient way to branch the code and choose a block of co
de to execute based on the value of an expression. 
     
   1  switch( expresssion ){
   2  case C_1 : block_1
   3  case C_2 : block_2
   4  case C_3 : block_3
   5  ...
   6  default: block0
   7  }
     
If the value of expresssion equals to C_i,  block_i will be executed. Here C_i must be a 
constant, but they can be of different types, that means, you can mix numbers and strings
as case values. Unlike in C/C++, no break statement is required to get out of the switch.


If you want to execute the same block of codes for different case values, you just need t
o put them together in the same case: 
     
   1  switch( expresssion ){
   2  case C1, C2, C3 :
   3      block3
   4  ...
   5  default: block0
   6  }
     
As a simple example, 
     
   1  a = "a";
   2  switch( a ){
   3  case 1, "a" : io.write("case 1 or a");
   4  default :  io.write("case default");
   5  }
     


 3.6   Break and Skip  

break can be used to exit a loop, and skip can be used  to skip the rest part of script a
nd start the next cycle of a loop. skip is equivalent to continue in C/C++.
     
   1  for( i=0; i<5; ++i ){
   2      io.writeln( i ); 
   3      if( i == 3 ) break;
   4  }
     


 4   Routines (Functions)     
 4   Routines (Functions)     
 4   Routines (Functions)     

Routine (function) is a relative independent block of code that can be repeatedly execute
d by invoking it when and where it is needed. It can accept parameters to changes its beh
aviour. It may also return results to its caller.

 4.1   Definition  

Dao routines are declared with keyword routine For example, 
     
   1  routine func( first, second )
   2  {
   3     first += 10;
   4     second += "test";
   5     return first, second; # return more than one results.
   6  }
   7  
   8  (ret1, ret2) = func( 111, "AAA" );
   9  ret3 = func( ret1, ret2 );
     
defines a function that can take two parameters as inputs, and return two values as outpu
ts.

 4.2  Parameter Type and Default Value 

Routine parameters can have type annotations, and a default value can also be specified f
or a parameter. 
     
   1  routine MyRout( name: string, index = 0 )
   2  {
   3     io.writeln( "NAME  = ", name )
   4     io.writeln( "INDEX = ", index )
   5  }
     
Here name is annotated as type string, and index is specified as an integer with default 
value 0. Any parameter after a parameter with default value must have default values as w
ell.

 4.3  Routine Overloading 

Routine overloading by parameter types is also supported in Dao, which means that multipl
e routines can be defined with the same name, but different parameter signatures. 
     
   1  routine MyRout( index: int, name = "ABC" )
   2  {
   3     io.writeln( "INDEX = ", index )
   4     io.writeln( "NAME  = ", name )
   5  }
   6  
   7  MyRout( "DAO", 123 ) # invoke the first MyRout()
   8  MyRout( 456, "script" ) # invoke the second MyRout()
     


 4.4  Anonymous Routine and Closure 

Dao supports routines as first class objects. So they can be created as anonymous routine
s or closures, and used just like other objects.

The syntax to create anonymous routine or closure is nearly identical to the definition o
f a normal function, except the following differences: 
  1. No need for a function name;
  2. Default parameter values do not need to be constant;
  3. Its function body may access the local variables of the outer function; 

When such function accesses local variables from its outer/upper scope, it is created as 
a closure, otherwise as an anonymous function.

Here is a simple example, 
     
   1  abc = "ABC";
   2  
   3  rout = routine( x, y: string, z = abc + abc ){
   4      abc += y;
   5      io.writeln( "lambda ", abc )
   6      io.writeln( "lambda ", y )
   7      io.writeln( "lambda ", z )
   8  }
   9  rout( 123, "XXX" );
  10  io.writeln( abc )  # Output: ABCXXX
     

For code section routines, please see dao.routine.section. For coroutine and generator, p
lease see module.core.coroutine.

 5   Classes     
 5   Classes     
 5   Classes     


Class is a user-defined data structure that supports data abstraction, encapsulation, pol
ymorphism and inheritance etc. It is commonly used to do Object-Oriented Programming (OOP
).

 5.1  Class Definition 

A class data strucutre is defined by composing data fields and member methods in a meanin
gful way that defines the states and behaviours for the instances of the class. Dao class
supports four types of fields: 
  *  constant: declared with keyword const;
  *  static variable: declared with keyword static;
  *  instance variable: declared with keyword var;
  *  instance invariable: declared with keyword invar; 
Such fields can be declared with or without explicit types, and with or without default i
nitialization values, in the same way as specifying types and/or default values for funct
ion parameters. For example, the following can be used for instance variables, 
     
   1  var variable;
   2  var variable = init_value;
   3  var variable: typename;
   4  var variable: typename = init_value;
     

Class constructors and ordinary methods must be declared with keyword routine. Methods fo
r overloading operators must use keyword operator. 

The visibilities of class fields and methods can be restricted by three permission keywor
ds: 
  *  public: publically accessible without restriction;
  *  protected: accessible from the class and its derived classes;
  *  private: only accessible from the class; 

Here is a simple class, 
     
   1  class ClassOne
   2  {
   3      var index = 0;
   4      var name  : string
   5      var words : list<string> = {}
   6  
   7      routine ClassOne( name :string, index = 0 ){
   8          self.name = name;
   9          self.index = index;
  10      }
  11  }
     

Within class methods, the special variable self represents the current class instance. Cl
ass methods may be declared inside class body and defined outside in the same way as in C
++, but in Dao, one should make sure that, the parameter list must be exactly the same in
the places for declaration and definition.

 5.2  Class Instance 

Class constructors are the methods that have name the same as the class name. A class ins
tance can be created by invoking a constructor of the class  in the same way as a functio
n call, 
     
   1  object = ClassOne( 'abc' )
     
Note that, the constructors are not used to create class instances, instead, an instance 
is created before, and then the constructor is called after to initialize the instance.

For a class without parent classes and without constructors,  its instances may also be c
reated by enumerating the members of the class, 
     
   1  class Point3D
   2  {
   3      var x = 0.0;
   4      var y = 0.0;
   5      var z = 0.0;
   6  }
   7  point = Point3D.{ 1, 2, 3 };
     
The names of instance variables may also be specified in enumeration, 
     
   1  point = Point3D.{ y = 2, x = 1, z = 3 };
     


 5.3  Methods and Properties 

There are three typical types of methods for Dao classes: static method, instance method 
and invariable/const instance method. Static methods can be invoked without class instanc
e objects, so they cannot access instance variables. The other two types of methods requi
res class instances to invoke. Instance methods can modify the instance variables, but in
variable methods cannot. Invariable methods can be declared by specifying "invar" after t
he brackets for the parameters. 
     
   1  class ClassTwo
   2  {
   3      private
   4  
   5      static state = 0
   6      var    value = 0
   7  
   8      public
   9  
  10      static routine Stat() {
  11          state += 1      # OK!
  12          state += value  # Error! Cannot access "value"!
  13      }
  14      routine Meth() {
  15          state += 1  # OK!
  16          value += 2  # OK!
  17      }
  18      routine InvarMeth() invar {
  19          state += value  # OK! Can access "value"!
  20          value += 2      # Error! Cannot modify "value"!
  21      }
  22  }
     

In order to provide access to the variables such as "value" in the above example, one can
define ordinary methods such GetValue() and SetValue(). But the better way is to use prop
erties. A property is a method that provides access to a field in a way that syntatically
looks like direct access. In Dao, this can be done by overloading name specific operators
such as .Name and .Name=. For example, 
     
   1  class MyNumber
   2  {
   3      private
   4      var value = 0;
   5  
   6      public
   7      routine MyNumber( init = 0 ){
   8          value = init;
   9      }
  10  
  11      operator .value(){ return value }
  12      operator .value=( newval: int ) {
  13          value = newval;
  14          io.writeln( "value is set" )
  15      }
  16  }
  17  
  18  num = MyNumber( 123 )
  19  num.value = 456
  20  io.writeln( num.value )
     


 5.4  Inheritance 
     
   1  class ColorRBG
   2  {
   3      var red   = 0.0;
   4      var green = 0.0;
   5      var blue  = 0.0;
   6  
   7      routine ColorRBG( R = 0.0, G = 0.0, B = 0.0 ){
   8          red = R;
   9          green = G;
  10          blue = B;
  11      }
  12  }
  13  
  14  yellow = ColorRBG( 1, 1, 0 ); # create an instance.
     
The following will define a derived class of ColorRBG, 
     
   1  class ColorRGBA : ColorRBG
   2  {
   3      var alpha = 0.0; # alpha component for tranparency.
   4  
   5      routine ColorRGBA( R = 0.0, G = 0.0, B = 0.0, A = 0.0 ) : ColorRBG( R, G, B ){
   6          alpha = A;
   7      }
   8  }
   9  
  10  magenta = ColorRGBA( 1, 0, 1, 0 ); # not tranparent.
  11  magenta.alpha = 0.5; # change to half tranparency.
     

In the definition of derived class, the parent class ColorRBG should be put after the der
ived class  and be separated with :.  The constructor parameters for derived class can be
passed to parent classes in the way as shown in the example.

There are several more advanced features based on class, please see dao.class for more in
formation.