Wiki
Version 19 (modified by kobi7, 11 years ago)

--

All of cobra in one page

The purpose of this page is to see usage by looking at sample code, and have a link to the thorough documentation.

SORRY, WORK IN PROGRESS

quick jump:

Keywords in Alphabetical Order

abstract adds all and any as assert base be body bool branch break callable 
catch char class const continue cue decimal def do dynamic each else end ensure
enum event every except expect extend extern fake false finally float for from 
get has if ignore implements implies import in inherits inlined inout int 
interface internal invariant is listen lock mixin must namespace new nil nonvirtual
not number objc of off old on or out override par partial pass passthrough post
print private pro protected public raise ref require return same set shared sig stop
struct success test this throw to to? trace true try uint use using var vari 
virtual where while yield 

comments:

# a one line comment

/#
a multi-line comment
multi?
yes.
 #/

basic structure:
very top level keywords are the optional "namespace" and "use"

top level keywords are:
interface, class, struct, mixin

inside interface are:

def, pro, get, set

inside class are:

def, var, pro, get, set, const, test
inside def there can be:

test, require, ensure, body - or the beginning of code.

examples:

interface IAudioPacket
    def toWavPacket as WavPacket


class WavPacket implements IAudioPacket
    cue init(bytes as uint8[]) # cue init is the syntax for constructor (ctor)
        base.init # it must call a base ctor.
        # ... etc: create the wav packet format, using the bytes
    
    def toWavPacket as WavPacket
        return this

class Mp3Packet implements IAudioPacket
    var bytes as uint8[]
    def toWavPacket as WavPacket
        wavBytes = Mp3Utils.decode(.bytes) # '.decode' is a shared (static) method. '.bytes' is a class variable.
        #methods without arguments, getters and public variables are accessed uniformly, with a '.' before their name.
        #local variables (inside a 'def') don't have the dot.
        wavpack = WavPacket(wavBytes) # instantiating a class. No need for the 'new' keyword in cobra.
        return wavpack

very useful for debugging are 'trace' and 'assert' }}}

    # trace example
    def linear(a as number, x as number, b as number) as number
        trace a,x,b
        res = a * x + b
        trace res
        return res

assert accepts a boolean, with one expression per line. example: ...

contracts example: without contracts you might get surprising values, not knowing why

def gap(a as uint, b as uint) as uint
    test
        assert .gap(7,9) == 2
    require
        0 <= a <= 1000 # in this way it's possible to constrain the valid range of arguments for this function.
        0 <= b <= 1000
        # a >= b # enable this line to find the error

    ensure # we add ensure because we got unexpected results, and it failed.
        result <= 1000 # the return value is assigned to the 'result' variable, so you can test it in the 'ensure' clause
    body
        res = a - b # is something wrong with this code? (when b > a, uint handles negatives by going to uint's maxvalue)
                    # a fix would be to check if a > b, a-b, else b-a
        trace res # prints out the value and variable name, along with location in code.

        return res   

mixin example:

mixin VolumeSupport
    invariant
        0 <= .volume <= 100

    pro volume from var as int
    def decVolume
        .volume = Math.max(0, .volume - 1)

    def incVolume
    .volume = Math.min(100, .volume + 1)

class Radio adds VolumeSupport  
    cue init
        base.init
    .volume = 0

class TV adds VolumeSupport 
    cue init
        base.init
    .volume = 0
class Program
    def main
    r = Radio()
    assert r.volume == 0
    r.incVolume
    assert r.volume == 1