- Cola (programming language)
-
Cola is a programming language similar to Java and C# with some higher level features of Perl and Ruby including first-class regular expressions. It can be compiled for the Microsoft .NET CLR or the Parrot virtual machine.
Cola is a compiled language with static type checking, but the designer mixed in some of the features more common to scripting languages like Perl and Ruby. According to the author, after years of using Java and C++ for large projects, and Perl for small to medium ones, there seemed to be no language to fill the gap. Cola is less of a new language "design" than a mix of several very powerful languages with the following key principles in mind:
Curly braces and semi-colons at the heart - C++, Java and Perl programmers should be comfortable, whitespace has no effect on the semantics.
Convention over Code - Things that are conventional don't need to be explicit (Java/C# public keyword on methods)
High signal-to-noise ratio - Use Convention over Code to reduce keyword clutter and improve readability. Don't clutter the expression of an idea with implementation of the idea. Java and C# exhibit this in their arguably poor choice of default scope access of fields and methods, ensuring the source files are riddled with scope access keywords. In practice, the use of the word public dominates Java and C# syntax, based on source code analysis of real-world samples. Cola implements different defaults, plus supports C++ style of scope access sections, as opposed to per-member keywords.
Strings and text processing are top priority - Most programming involves strings and text manipulation. Supporting regular expression dramatically increases the power of a language, but BUILTIN syntax for regular expressions improves the readability. When combined, they increase the productivity of the programmer. In cases of assignment or use of a non-string variable in string, or ambiguous context, Cola will choose to convert to string if a conversion exists, rather than force an explicit cast. A compiler switch can enable strict or warning mode regarding auto-casting.
Scriptlets should be possible - A default class with a static main is not required just to do a small job.
A Hello world program written in three ways:
// C/Perl-style without classes // Cola package/global methods are static by default, void by default string mesg = "Hello world\n"; main() { print(mesg); }
// Cola OO-style // classes, methods and constructors public by default, fields private by default class Hello { string mesg; new() { mesg = "Hello world\n"; } static void main() { print(mesg); } }
// Cola OO-style, explicit scope access (C++ style) // classes, methods and constructors public by default, fields private by default class Hello { protected: string mesg; public: new() { mesg = "Hello world\n"; } static void main() { print(mesg); } }
Rather than name constructors after the class name in the tradition of C++/Java/C#, Cola uses "new" and "delete" for constructor and destructor names, to simplify the appearance of code, improve cut-and-paste productivity.
Cola provides both prefix and postfix array declaration notation, and both static and dynamic arrays. This is a productivity choice by the author, to improve comfort for diverse programmer background (C/C++ vs Java/C# style), and to reduce notation (static arrays).
int[] arr = new int[12]; // prefix, dynamic int arr[] = new int[12]; // postfix, dynamic int[12] arr; // prefix, static auto-allocated int arr[12]; // postfix, static auto-allocated
An example of Cola's support for regular expression and matching is given below. First a conventional example that echoes Perl's approach.
// implicit match backreference if(mesg =~ /(yes)(madam)/) { print("In string: " + $0); print("we matched: " + $1 + ", " + $2); }
Cola includes a more powerful, expressive notation for matching called match aliasing. Simply put, any match expression can declare an object of type match as part of the expression (similar to the spirit of declaring a named iterator with C++ or Java in a for loop: for(int i = 0; i < 100; i++)
// explicit named match example if(str =~ /foo(bar)/ as match1) { // default is matchA print(match1.$1); }
For the scope of the if statement, match1 is in scope and can be used for clarity. The advantage to match aliasing is more evident when we have multiple, nested matches.
if(str =~ /foo(bar)/ as match1) { // We can use a backreference in a new match expression // $1 refers to match1 until a new match expression, after which // it refers to the new match in immediate scope. To refer back // we use match1 alias (match1.$1) if($1 =~ /b(ar)/ as match2) { print(match1.$1); // match1 still in scope print(match2.$1); // match2 now in scope, and the default print($1); // same as match2.$1 } }
Cola includes some static type inference via the "var" keyword (similar to C#), as well as a shorthand "new" notation where the type is inferred from the right side.
// equivalent var s = new Dog(); Dog s = new;
Also supported is a virtual constructor, to create objects from another object.
Animal a = new Dog(); Animal b = a.new(); var v = a.new(); // v will be of the Animal type, but receives a Dog
Cola includes a foreach() statement, currently supporting iteration on arrays and the builtin .NET non-generic types in System.Collections, or any class that implements "IEnumerator GetEnumerator()". Generic support is underway. Cola foreach() is implemented similar to the C# compiler, generating array iteration code when arrays are used, and using the IEnumerable interface or GetEnumerator() convention.
// Uses .NET System.Collections var list = new System.Collections.ArrayList(); // note the inferred type list.Add("LITTLEDOG"); list.Add("BIGDOG"); list.Add("LITTLECAT"); list.Add("BIGCAT"); foreach(string s in list) { // Nested named matching if(s =~ /(LITTLE|BIG)/ as size) { if(s =~ /(DOG|CAT)/ as animal) print("Animal is a " + size.$1 + " " + animal.$1); } }
Use of most of the .NET CLR libraries is currently supported, though with unfinished support for the "using" namespace import, the programmer must fully qualify types as of 0.4.
// System.IO.File sample main() { foreach(var line in System.IO.File.ReadAllLines("flintstones.txt")) if(line =~ /FRED/) print(line); }
// .NET System.Xml Example main() { var doc = new System.Xml.XmlDocument(); doc.LoadXml("<book genre='novel' ISBN='1-861001-57-5' misc='sale item'>" + "<title>The Handmaid's Tale</title>" + "<price>14.95</price>" + "</book>"); var myElement = doc.get_DocumentElement(); print(myElement.ToString()); print(myElement.get_InnerXml()); }
// Oracle.DataAccess sample main() { string first, last; var conn = new Oracle.DataAccess.Client.OracleConnection("Data Source=DEV;User Id=scott;Password=tiger;"); conn.Open(); var cmd = new Oracle.DataAccess.Client.OracleCommand("select first_name, last_name from doctor", conn); var reader = cmd.ExecuteReader(); while(reader.Read()) { first = reader.GetString(0); last = reader.GetString(1); print(first + " " + last); conn.Close(); }
Cola can currently compile against a significant portion of the .NET CLR standard libraries, with noted lack of support for generics, pointer / unsafe types and delegates. Full support for these features is planned.
A current alpha version of the Cola compiler for .NET is available via email from the author (Melvin Smith).[1]
References
External links
Categories:- .NET programming languages
Wikimedia Foundation. 2010.