cowlark.com :  cowbel :  Some Examples

cowbel

Some Examples

Published: 2016 November 3

Hello, world

The original and best example program.

#include "SimpleIO.ch"

println("Hello, world!");

In cowbel, the program body is the main function, so you the only boilerplate you need is the I/O library. (An empty file is a valid cowbel program that does nothing.)

FizzBuzz

FizzBuzz is the classic bottom-level interview question, designed to demonstrate basic competency. The problem is: write a program the displays the numbers from 1 to 100. Except, instead of multiples of three print "Fizz", and instead of multiples of five print "Buzz". For numbers which are multiples of both three and five, print "FizzBuzz".

Here's how to do it in cowbel.

#include "SimpleIO.ch"

for i = 1, 101
{
  if ((i % 15) == 0)
    println("FizzBuzz");
  else if ((i % 3) == 0)
    println("Fizz");
  else if ((i % 5) == 0)
    println("Buzz");
  else
    println(i.toString());
}

(Yes, the 101 is intentional --- for loops take values in the range [from, to), so the upper value is exclusive.

99 Bottles of Beer

Another example favourite.

#include "SimpleIO.ch"

function bottle(n: int)
{
  printi(n);
  if (n == 1)
    print(" bottle");
  else
  print(" bottles");
}

function sing(verses: int)
{
  do
  {
    bottle(verses);
    println(" of beer on the wall,");
    bottle(verses);
    println(" of beer,");
    println("Take one down, pass it around,");

    verses = verses - 1;

    bottle(verses);
    println(" of beer on the wall.");
    println("");
  }
  while (verses > 0); 
}

sing(10);

There shouldn't be any surprises here. Note the Javascript-style functions; these can be arbitrarily nested. Types on function parameters (and on return parameters) are mandatory.

Generics

Cowbel has support for generics in both types and functions. The standard library contains simple implementations of generic arrays and maps which can be used with any (compatible...) type.

#include "SimpleIO.ch"
#include "Map.ch"

var map = Map.New<int, string>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");

function lookup<K, V>(map: Map<K, V>, key: K)
{
  var value = map.get(key);
  println("The value of " + key.toString() + " is " + value);
}

lookup<int, string>(map, 3);
lookup<int, string>(map, 1);
lookup<int, string>(map, 4);
lookup<int, string>(map, 2);

qsort

Here's a more complex example that combines interfaces, generics, nested functions, recursion, and a few other features. This is an implementation of qsort which will sort any object that implements Array<T> for any T which implements the < operator. (This is the code that's in the standard library.)

function Sort<T>(array: Array<T>)
{
  function swap(a: int, b: int)
  {
    var t = array.get(a);
    array.set(a, array.get(b));
    array.set(b, t);
  }

  function sortlet(left: int, right: int)
  {
    if (left < right)
    {
      var pivot = array.get((left + right) / 2);
      var ln = left;
      var rn = right;
 
      do
      {
        while (array.get(ln) < pivot)
          ln = ln + 1;
        while (pivot < array.get(rn))
          rn = rn - 1;

        if (ln <= rn)
        {
          swap(ln, rn);
          ln = ln + 1;
          rn = rn - 1;
        }
      }
      while (ln <= rn);

      sortlet(left, rn);
      sortlet(ln, right);
    }
  }

  var lo, hi = array.bounds();
  sortlet(lo, hi-1); 
}