Jump to content

User:Phoolimin/Dao (programming language)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by GoodSirJava (talk | contribs) at 13:03, 17 October 2007 (moved Dao Language to Dao (programming language): Consistency and clarity). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Dao
File:Dao logo.png
ParadigmMulti-paradigm
Designed byLimin Fu
First appeared2006
Stable release
dao-devel / 2007-04-09
Typing disciplinestatically typed or dynamically typed
OSCross-platform
LicenseLGPL License
Websitewww.xdao.org
Influenced by
C++, Lua, Python, Perl

Dao is an object-oriented scripting language with dynamically typed variables supporting complex data structures. It has powerful text processing abilities, such as regular expression matching. It provides a wealth of built-in numerical data types such as complex numbers and multi-dimensional numeric arrays, as well as their corresponding arithmetic operations. Support for multi-threaded programming is also an integrated part of Dao. The interpreter of this language is implemented as a light-weighted and efficient virtual register machine (Dao VM) in standard C. The Dao VM can be easily extended with C/C++, through a simple and transparent interface. It can also be easily embedded into other C/C++ programs.

More advanced features of the language includes: mixed static- and dynamic- typing system that allows explicit or implicit type declaration of variables, and is capable of automated data type deduction; a flexible macro system that allows definition of new syntax; concurrent and distributed programming with message passing interfaces; mixed programming with C language using TCC.

Basics

Hello World

The classic hello world program can be written as follows:

stdio.print ( "Hello world!" )

Here stdio is the standard library to handle input and output. In Dao, there are no built-in functions; all functions are part of a certain library, such as stdio, stdlib, math, coroutine, reflect, mpi (message passing interface), network, and thread.

The stdlib.listmeth routine can be used to display the methods in a library. The methods in math, for example, can be displayed using:

 stdlib.listmeth ( math )

Data Types

A Dao variable can be declared by assign the result of an expression to a variable name.

 a_number = 123
 a_string = "abc"
 a_list = { 1, 2, 3 }
 a_hash = { "CD"=>123, "AB"=>456 }
 a_vector = [ 1, 2, 3 ]
 a_matrix = [ 1, 2; 3, 4 ]

By default, a variable will have a fixed type that is inferred from the expression that is used to declare the variable, this is so called implicit typing. The type of a variable can also be specified explicitly as

 var_typed : type
 var_typed : type = value

type can be one of the following keywords for built-in types: int, float, double, string, complex, list, hash, array, buffer, routine, and composition of them. type can also be a Dao class name or the name of a user-defined C type. Special keywords/symbols for typing include: any for any types, ? for undefined types and @X for type holder that can be initialized to certain type in parameter list.

For example,

 a_list2 : list<list<float> >
 a_list3 : list<list<string> > = {}
 a_hash2 : hash<string,int> = { "ABC"=>123 }

Typed variables are subjected to compiling time checking for type consistency for operations.

Control Flow

If-Elif-Else:

 a = math.rand();
 if( a > 0.75 ){
    a -= 0.75
 }elif( a > 0.5 ){
    a -= 0.5
 }else{
    a -= 0.25
 }
 

While:

 i = 0;
 while( i < 10 ) i++

For:

 for( i=0; i<10; i++ ) stdio.println( i )
 for( i=0 : 9 ) stdio.println( i )
 for( i=0 : 2 : 9 ) stdio.println( i )

For-in:

 a_list = { 1, 2, 3 }
 for( it in a_list ) stdio.println( it )
 a_list2 = { "a", "b", "c" }
 for( it in a_list; it2 in a_list2 ) stdio.println( it, it2 )

For-in also works for hash.

Switch

 a = "abc"
 switch( a ){
   case 1 : a += 123;
   case "abc" : a += "456"
   default : stdio.println( "default case" )
 }

Routine(Function)

 routine foo( a, b : string, c = 123 ) => int
 {
    return 456;
 }

Dao supports high order functions. The definition of such functions is identical to the normal function definition, except the following difference: (1), there is no need for a function name, but the created function must be assigned to a variable; (2), the default value expressions do not necessary to be constant expressions, they are evaluated at running time when the function is created; (3), the function body may contain variables defined in the "upper" function that creates it.

 a = "ABC";
 rout = routine( x, y : string, z = a+a ){
    a += "_abc";
    stdio.println( "lambda ", a )
    stdio.println( "lambda ", y )
    stdio.println( "lambda ", z )
 }
 rout( 1, "XXX" );

Class

 class MyNumber( value = 0 )
 {
   private
   my Value = 0; # default value is zero
   Value = value;
   public
   routine setValue( value : int ){ Value = value }
   routine getValue(){ return Value }
 }

Macro

In Dao macros are defined in the following way, the syntax patterns are written in BNF-like representation:

 syntax{
   source_syntax_pattern
 }as{
   target_syntax_pattern
 }

The following syntax will support "while-do-end" without brackets,

 syntax{
    while $EXP do \[ $BL \] end
 }as{
    while( $EXP ){ \[ $BL \] }
 }

Concurrent and Distributed Programming

Asynchronous Function Call

Probably, the simplest way to create multi-threaded programs in Dao is to use asynchronous function calls (AFC). The way of using AFC is almost identical to that of normal function calls, with the exception that the keyword async must follow the call.

 myfunc( myparams ) async;
 myobj.mymeth( myparams ) async;
 

Any functions or methods can be invoked in such asynchronous way.

Normally AFC is executed in a separated native thread, which can be either an idle thread available from the thread pool, or a new thread created on the fly.

Message Passing Interface

With Message Passing Interface APIs provided in library mpi, one can easily do concurrent and distributed programming in Dao. In the MPI library, there are 3 principle functions: spawn(), send() and receive(). With spawn(), one can create lightweight virtual machine processes or real operation system processes, in the local or remove computers; and with send() and receive(), a process can send message to or receive message from other process.

The process names are of the following form:

 virtual_process@real_process@@hostname

"@real_process@@hostname" identifies an operating system process on host "@@hostname", and "virtual_process@real_process@@hostname" identifies a virtual process within "@real_process@@hostname". Message passing can only happen among virtual processes. Each real process has a main virtual process named "self". Any part can be omitted. For example, when "virtual_process" is omitted, it means the "self" virtual process, and "@@hostname" alone identifies the "self" within the operating system process that binds to port 4115 ( D : 4, A : 1, O : 15 ).

 # spawn a real process to run script "mpi_script.dao"
 mpi.spawn( "@pid", "mpi_script.dao" );
 # spawn a virtual process to run function "test"
 mpi.spawn( "vmp@pid", "test" );
 # send message to a real process
 mpi.send( "@pid", "TO MAIN" );
 # print a received message
 stdio.println( mpi.receive() );
 # spawn a real process on "@@localhost" to run script "mpi_script.dao"
 mpi.spawn( "@pid2@@localhost", "mpi_script.dao" );
 # spawn a virtual process on "@pid2@@localhost" to run function "test"
 mpi.spawn( "vmp@pid2@@localhost", "test" );
 # send message to the virtual process "vmp@pid2@@localhost"
 mpi.send( "vmp@pid2@@localhost", "ANOTHER", 123.456 );b