Tuesday, March 23, 2010

Examples from RosettaCode

Type equivalence:

(a == b) = true
(a == b) = false
(b) a or a.castTo(b) will return a value of type b or an error (of type b).

Eval:

eval(\" x \") = x // define an eval (uses current scope/environment)
x = 1
eval("x") // 1
eval("x+1") // 2

// you can provide type safety
pure(eval("print \"x\"")) // error (with no value)
pure(eval("\"x\"")) // x

// ^ pure is a cast from an impure function to a pure function, obviously

// you can create another eval with null scope:
// This is probably not what you want, as the null scope won't do anything
evalEmpty = {
  eval = eval;
  #parentScope=null;
  eval(x)
};

evalEmpty("1+2") // 1+2 - I told you it doesn't do anything!

evalWithScope = {
  parentScope = scope;
  eval(x)
};

evalWithScope(rootScope, "1+2") // 3
evalWithScope(#scheme#.rootScope, "(+ 1 2)") // 3
x = 1+2
evalWithScope(currentScope, "x") // 3
Scopes include rootScope, #language#.rootScope, and currentScope. You can get more complicated if you want by creating other scopes.

Ethiopian multiplication:

half(x)   = x >> 1   // pointfree: half =  >> 1
double(x) = x << 1   // pointfree: double =  << 1
even(x)   = x % 2==0 // pointfree: even = ! (% 2)
ethiopian(x,y) = (even(x) ? 0 : y) + ethiopian(half(x), double(y))
x ethiopian y = ethiopian(x,y)

Link time:

Link time will occur between program input and execution at any time that files to link have been specified.

Tclkit:

One file suffices for execution of programs.

FIFO (usage):

// Init

// pick your favorite constructor
fifo = new List()
fifo = List()
fifo = List
fifo = []

// Error handling
x = peek(fifo) // x = underflow
x = pop(fifo)  // x = that same underflow
index = fifo.push(x) // index = -1, fifo[index] = x = underflow. get it?
empty(fifo) //true
x,fifo2 = pop fifo // if you're not a fan of mutation or parenthesis
fifo2 == fifo // false; underflowing is not ignored

// Normal usage
fifo.push(1)  // fifo = [1]
push(fifo, 2) // fifo = [2,1]
pop(fifo,x) // x = 2, fifo = [1]

no = empty(fifo) //y = false
empty(fifo) = true // empties fifo
x = fifo.peek() // x = underflow
/* fifo.empty = false */ // gives a type error
fifo.empty = no // fifo returns to previous state

pop(x, fifo) // x = 1

Amb:

// Some cool list syntax
set1 = "the"    | "that"     | "a"
set2 = "frog"   | "elephant" | "thing"
set3 = "walked" | "treaded"  | "grows"
set4 = "slowly" | "quickly"

a/"(.*)(.)"/ amb b/"(.)(.*)"/ = (a$2 == b$1) ? a " " b

print (set1 amb set2 amb set3 amb set4)

Dynamic variable names:

name = in.readString();
this[name] = 1; // due to table-object correspondence

API's:

I will steal borrow them from other languages!

Simulate mouse click:

System.Hardware.Input.Mouse.click(x,y)
Namespaces because I feel like it. Acceptable targets depend on privilege level and where/how you got x and y.

Run-length encoding:

#brace-style python // because I just don't care anymore
for(x in string)
  run = 1
  while(x == x.next)
    run++
    x = x.next
  out << run << x

Inheritance:

Animal = { eat, noise }
Dog = Animal
Dog.noise = "Bark!"
Dog.eat = "Dog chow"
Lab = Dog
Collie = Dog
Collie.eat = "Scraps from the table"
Cat = Animal
Cat.noise = "Meow"
Cat.eat = "Mice"

// = is a pretty powerful operator

Apply a callback to an Array:

array.each(callback)
callback(array)
array | callback
map(array, callback)
for( i in array ) callback(i);

Environment variables:

System.Environment["TEMP"]
Dependent once again on privilege level

Bitwise operations:

// because bit operations are byte operations
a & b = {{00}{01}}[a][b]
a | b = {{01}{11}}[a][b]
a ^ b = {{01}{10}}[a][b]
~a    = {10}[a]
// add more here...
a << b
a >> b
a >>> b
rotateLeft(a, b)  // a >^ b ?
rotateRight(a, b) // a ^< b ?

Conway's Game of Life:

grid[_,_] = 0
grid[2,1..3] = 1
neighbors[livecount,cellvalue] = 0 // livecount includes the cell itself
neighbors[3,0] = neighbors[4|3,1] = 1

do {
  print(grid);
  newgrid[x,y] = neightbors[sum(grid[x-1..x+1,y-1..y+1]),grid[x,y]];
  grid = newgrid;
} to 3;

Simple Random Distribution Checker:

srdc(generator, times, delta) {
distribution = {};
do {
  distribution[generator.next()]++;
} to times;
distribution /= times;
skew = (max - min)(distribution);
if( skew / 2 > delta)
  print(error)
}