Archive

Archive for February, 2012

The Bike Programming Language

February 19th, 2012 6 comments

Bike is a programming language that I develop.  I worked on this interesting toy project a while ago.  I was hoping to have had time to improve it further (plenty of things I want in a language) before announcing it in my blog.  However, work at my new startup has been so hectic (surprise, surprise…) that I can hardly find time to continue, so I guess I just put it out to the public and get everyone’s opinions.

In a nutshell, Bike is an interpreted language running on Windows and Mac/Linux (via Mono).  I developed Bike with the intention of building a language feel most natural by me so that I can use for daily programming tasks.  And since the existing languages that already feel natural to me are Ruby, JavaScript and C#, no surprise that these languages influenced Bike a great deal.  From the language perspective these are the important characteristics of Bike:

  • Dynamic and strong typing
  • Everything is an object
  • Prototypal inheritance
  • First-class function
  • CLR interoperability

No further ado, here’s some Bike.  First, hello world.

print 'Hello, world!'

Everything is object (note that the print function is passed as argument)

10.times( print );
0.upto( 10, print );

Calculating Fibonacci (return keyword is optional, semicolon is optional in the last statement of a block)

func fib( n ) {
    n <= 2 ? n : fib( n - 1 ) + fib( n - 2 )
}
print( "n: " );
var n = readln();
println( fib( n.to_number() ) );

Self-executing function

( func() {
    println( 'executed' );
} )();

Closure

var f = ( func( a, b ) {
     var c = 1;
     return func() { a + b + c };
} )( 2, 5 );
println( f() );

Currying

Bike.Function.curry = func( *args ) {
	if ( args == null || args.size() == 0 ) return this;
	var me = this;
	return func( *more ) {
		if ( more != null )
			args.add_all( more );
		me.call( this, *args );
	};
};

func add( a, b ) { a + b }
var addTo2 = add.curry( 2 );
println( addTo2( 3 ) );

add = add.curry( 2, 3 );
println( add() );

Var-args and array expansion

func add_all( *numbers ) {
    numbers.reduce( 0, func( current, ele ) { current + ele; } );
}
println( add_all( 1, 2, 3 ) );
println( add_all( 1, 2, 3, 4 ) );

var arr = [ 1->10 ];
println( add_all( *arr ) );

Inheritance

var Person = {
    initialize: func( name ) {
        this.name = name;
    },
    to_string: func() {
        this.name;
    }
};

# clone person and invoke initialize on the new obj
var buu = Person.create( 'Buu' );
buu.fav_language = "Bike";
buu.to_string = func() {
    this.super( 'to_string' ) + "'s favorite language is " + this.fav_language;
};
println( buu );

.NET Interoperability

var list = System.Collections.ArrayList();
[ 0->9 ].each( func( i ) { list.Add( i ); } );

for ( var e in list ) print( e + ', ' );

0.upto( list.Count, func( i ){println( list[ i ] );} );

Dynamic code evaluation

var code = 'println( "This is cool!" );';
exec( code );
code = '2 * 3;';
println( exec code );
code = 'var person = {name: "John"};';
println( ( exec code ).name );
println( person.name );

There are more interesting features, but I guess that’s enough for you to get a feel of Bike. if/else/while/for/switch/rescue are all available but they are probably not needed much.  Bike also comes with a minimal base class library to work with file system, multithreading, HTTP, JSON, regex, unit test etc.  All these are written in Bike itself (mostly .NET wrapper since it’s fast to implement although pure native implementation would be interesting).

Go to https://github.com/buunguyen/Bike and check out the samples folder for more.  Interested?  Fork and contribute to the language and/or base class library.  Questions, ideas and feedback, please comment or email (see About).  Thanks and happy biking!