Release Notes

Cobra Release 0.8

Cobra 0.8 adds built-in sets, extensions, bitwise operators, a configurable number type, a -turbo option and numerous refinements. There are also 30 bugfixes.

Some of the bugs fixed in this release are in support of using the GTK# and Tao.SDL libraries.

There are new How-To's that accompany this release:

The How to Write Basic Syntax now covers if statements, while loops, putting statements on the same line and line continuation. The "Translate Psuedo Code To Cobra" How-To's linked above also cover declaring methods that accept references to methods.

Additions

Built-in Sets

ISet<of T> and Set<of T> are now part of the Cobra standard library. Sets are unordered collections of arguments with fast membership testing via element in someSet or someSet.contains(element). Depending on the size of the collection, testing for membership can be hundreds of times faster with a set than with a list.

As with lists and dictionaries, there are literals for sets such as {1, 2, 3} and {,}. Sets are enumerable so they can be used with for..in loops and passed wherever an enumerable is expected. Sets and lists both have an initializer that accepts an enumerable argument, so converting between the two is easy.

The equality operators, == and <>, are available for sets which are considered equal if their contents are equal (regardless of whether their generic type argument is equal).

class Example def main is shared x = {1, 3, 5} y = {2, 4, 6} assert 3 in x assert 3 not in y assert x.intersection(y) == {,} assert x.union(y) == {1, 2, 3, 4, 5, 6} assert x.count == 3 # eliminate duplicates in a list names = ['Python', 'C#', 'Python', 'Eiffel', 'Objective-C', 'Eiffel'] uniqueNames = Set<of String>(names) assert uniqueNames.count == 4

The empty dictionary literal is now {:} to distinguish it from an empty set. The literal {} still works for empty dictionaries, but generates a warning to use {:} or {,}.

Extension Methods

You can now add methods to existing types, even ones from DLLs that you don't have the source for. This feature is similar to Smalltalk and Objective-C categories, and C# and VB's extension methods. Unlike C# and VB, you can use this feature even in .NET 2.0.

Here is an example taken from CobraLang.cobra which now enhances lists to have a "swap" convenience method:

extend System.Collections.IList def swap(i as int, j as int) temp = this[i] this[i] = this[j] this[j] = temp

So now you can write someList.swap(i, j). You can also extend classes and structs such as String and DateTime.

In addition to "enhancing" library classes, another use would be to organize your code. For example, you could add UI oriented methods to domain objects, but put them in extensions in a separate file. Then if you implement another form of UI (say WUI vs. GUI), you can easily exclude the old UI methods.

Note that the compiler will only "see" extension methods that are in your current namespace or brought in via "use" directives (as in use Some.Name.Space).

As with ordinary methods, you can have test sections and contracts.

There are some limitations to extensions that will be addressed in the future:

Numeric Additions

# cobra -number:float32 example.cobra class Example def compute(a as number, b as number, c as number) as number return a * b + c

This option enables you to experiment with decimal vs. float64 vs. float32 in order to see how the choice of numeric type affects performance, memory consumption and accuracy. This option is also important for keeping Cobra convenient when libraries for math, games, simulation, etc. use a non-decimal numeric type (typically float64).

# forms: for x in start : stop : step print x for x in start : stop # step of 1 is assumed print x for x in stop # start of 0 is assumed print x # examples: list = ['qwerty', 'dvorak'] for i in list.count list[i] = list[i].toUpper for i in 0 : 100 : 2 print i

Unlike the old numeric for loop, the parameters to the loop are evaluated only once. In other words, the stop and the step are not re-evaluated each iteration of the loop. If you need that kind of behavior, use the general purpose while loop.

Command Line Additions

Minor Language and Compiler Refinements

Argument 1 of method "bar" expects a non-nilable type (A), but the call is supplying a nilable type (B?).

Bugfixes