Introduction

I'm developing this language because I don't find the other languages perfect
for everything. C++ is known to be one of the fastest languages, but its
syntax (especially header files) and the lack of C# like high level features makes
developing slower in my opinion. Debugging can be also hard in C++. But C# is a
managed language and it limits low level programming and application
performance. 3D graphics is about 1.5-2 times slower in
C# than in C++.

I have been working on Bird since March 2010 in C#. It's a strongly typed
native language. Its performanceeseems to
be competitive with C++ compilers currently and it's going toand it's going to
have features
from high level languages besides new things. There are many things that I
haven't implemented yet, but it can be used for smaller programs. The syntax is
similar to C# and C++ with some modification in order to make code smaller and
improve readability. I was planning to make a C# parser too, but I stopped
working on it for now. I will start working on a new in the future. The
libraries are similar to .NET, the basic functions are going to be implemented.
So I think it won't be hard to understand.

Requirements for Running a Program

Samples have a C++ equivalent code to compare performance. In order to
compile them MinGW, Clang
are needed to be installed and set in the PATH variable, but it's optional.
Visual C++ compiler usage requires the path to "vcvarsall.bat" in to be set
in "Run - VC++.bat" files.

Creating Programs with Bird

The compiler can be run from command line by "Bird.exe" which is in
the
"Binaries" directory:

I've made .bat files for the samples, so using command line for them
is not needed.
The -x means that the compiler should run the output file after
it had been compiled. The input files
can be Bird files, C, C++ or Object files.

Libraries can be specified by the -l option. Currently the
BirdCore and BlitzMax are available that are included by default. The -nodefaultlib
disables them. BlitzMax is another programming language,
its functions are needed for graphics because I haven't implemented them yet.

Object and archive files also can be the output file to use it in other languages. It can be specified
with the -format attribute. These are its possible values:

app

Executable file

arc

Archive file, it doesn't contain the libraries, they need to be
linked to the exe.

obj

Object file, only contains the .bird files' assembly.
The other files and libraries are not included.

Syntax

A Simple Function

using System
void Main()
Console.Write "Enter a number: "var Number = Convert.ToInt32(Console.ReadLine())
if Number == 0: Console.WriteLine "The number is zero"elseif Number >0: Console.WriteLine "The number is positive"else Console.WriteLine "The number is negative"forvar i in1 ... 9
Console.WriteLine "{0} * {1} = {2}", i, Number, i * Number
Console.WriteLine "End of the program"

The indication of code blocks are done based on the whitespaces in front of lines.
One scope always have the same number of whitespaces. Colon can be
used to make the command able to have the inner block in the same line. The
compiler needs to know where the previous expression ends. If there's no
expression, like the else statement without if, the colon is not needed.

Functions can be called without brackets, if the
returned value is not used. In the for loop the var
keyword means the type of i, which is the same as the initial value
(1 -> int). The three dots means that the
first value of i is 1, and it includes the value at
the right side, so the last value is 9.

I was thinking about making able to declare variable without type (or the
var keyword), but it could lead to bugs if the name of the variable
is misspelled.

Literals

Number literals can have different radix and type. $ means
hexadecimal, % means binary. Hexadecimal letters have to be
uppercase to distinguish them from the type notation, which is the lowercase short form of
the type at the end of number:

$FFb // An unsigned byte
-$1Asb // A signed byte
%100 // A binary number

Chained Comparison Operators

I think that this could have been implemented in C languages, because in
some cases it can be useful. Each sub-expression runs only once, so it's also faster that making
two relation connected with and.

The relation operators can only face to one direction to make them
distinguishable from generic parameters.

Aliases

It's similar to the using alias directive in C# and the typedef
keyword of C++, but in Bird aliases can be created for everything, even for
variables. The order of declaration doesn't matter, so it's possible to do
this:

Tuple Extraction

It's possible to extract a tuple in a similar way as swapping variables:

float x, y, z
x, y, z = Cross(a, b)

Or if var is used, it can be written in a single line:

(var x, var y, var z) = Cross(a, b)

The var have to be written before all the variable in order
to make the compiler able to decide which is an existing variable. E.g. if (var x, y, z) = ... would be
interpreted as three new variable then it wouldn't be possible to refer to
an existing y, z.

For Loops

forvar i in0 ... 9forvar i in0 .. 10

Both loops mean the same. Two dots means that i won't have
the value at right, in case of three dots it will have that value.

forvar x, y in0 .. Width, 0 .. Height

This is the same thing as two nested loops. The x goes from
0 to Width-1, the y goes from 0
to Height-1. The loop with y variable is the inner
one. The break command exits from both. It can be also
written like this:

forvar x, y in (0, 0) .. (Width, Height)

If only one number is specified then it will be the initial or the final
value of all variables.
So this is the same as the previous:

forvar x, y in0 .. (Width, Height)

If there is two point, it's possible to make a single for loop that
runs with all points that are in their rect. In this case the x
variable goes from P1.0 to P2.0, the y
goes from P1.1 to P2.1:

The step can be used to specify how much the loop variables
are increased. It can be both a scalar or a tuple with the same rules. It
adds 1 to i and 2 to j
at every cycle. The next loop increases i with 1
and j with 2:

forvar i, j in1 .. 20 step (1, 2)

Other Loops

The while, do-while loop is similar to C
languages:

var i = 1while i <100
i *= 2
i = 1do
i *= 2while i <100

I created two new that the code can be written smaller with. The repeat does something as many times
as specified in the parameter. the cycle makes an infinite
cycle.

Structures

Structures can contain fields, methods, constructors, etc. The new
operator, if the type is not specified, it creates an object with the same
type as it is converted to. In this program it is the return type. The
original is the var type that is always automatically changed
to another type:

Reference Typed Arrays

The compiler takes into account how many dimension are there before
interpreting the initial values. The values can be separated with both
brackets and new lines. If it founds one less dimensions than specified, the
new lines are dimension separators too. I'm not sure it's good, I may remove
it the future because it's a bit ambiguous. But it can be also made with
using only brackets.

The FixedArr1D_2 array can be declared without an error, because the
compiler takes the type of the variable into account before evaluating the
initial value.Fixed size arrays can be converted to reference types with an implicit
conversion:

The type of [Width, Height] expression is uint_ptr[2], so when it casted to

uint_ptr*

the compiler have to query the address. So it creates a new
variable that will be assigned to [Width, Height] and it gets the
address of this variable. It does the same with &Length in the
second function.
reinterpret_cast basically does nothing, it just changes the type of an expression node like casting a pointer.

Reference Equality Operator

The === and !== operator can be used to compare
the references of objects. It does the same thing as the

Object.ReferenceEquals

. The == can be also used for
this, but it can be overwritten with an operator function.

publicbool StringReferenceEquals(string A, B)
return A === B

Higher Order Functions

The type of a function can be marked with ->. At the left side
there are the input parameters, at the right side the output parameters. The
calling convention and modifiers also can be specified. E.g.

birdcall
string, object -> int, float

. When there are multiple outputs, the
return type becomes a tuple. In the future I plan to allow all functions to have
multiple output in a similar way.

This little sample shows how it works. I made it in C# too, and these are the
performance result with my machine:

Compiler

Bird

C#

Time

719 ms

2234 ms

Actually it is implemented very simply. Higher order functions are just a
tuples of an object and a function pointer

(object Self, void*
Pointer)

. The Self member can be null if the function is
static. It's possible to create a static function pointer with the

static

keyword: static int -> float. When a nonstatic
function is called, the Pointer member is converted to a
function pointer. If the Self is not null, it is also added to
the parameters. This is how the Test function is extracted:

Comments and Discussions

Very interesting. As a person who has actually designed and implemented two whole programming languages (that you've never heard of, but one was in commercial use) let me say that bird is a pretty impressive effort. Don't let the haters discourage you. Unless they've designed a programming language themselves, they have no standing to complain about anything you chose to do. Notice the haters don't say, "Your syntax is crap because..." or "Your language should do it this way..."

The syntax (controlled statements indented) is like python. Same with the tuple idea, sort of. Do you know python? If not, you should have a look, as python seems to be pointed at solving many problems you also are interested in.

My advice for programming language designers is to become familiar with as many other languages as possible. Then you can say, this feature is like python and that feature is like java, and so forth.

A previous poster said you should talk more about why you picked certain features, and I agree. It's much harder for the haters to call your efforts junk if you can express a reason for each design decision. It may also raise the quality of suggestions you get.

Thank you. I haven't used Python, but I read something about it. The indenting idea came from it I think, but I didn't know that there are tuples Python. In my opinion the drawbacks of Python are duck typing and performance.
In the article there are many things to be rewritten/corrected, I want to improve it, but when I have time, I usually rather do programming. I will try to write more about why I made the features in the next version.