The 2E Programming Language



About
News
Getting Started
Examples
Reference

Mandelbrot set fractal

#!/usr/local/bin/ee

# This 2e script will compute the Mandelbrot set, from (-2,2) to (2,-2), at
# a resolution of 80 x 40; results are displayed in ascii.

# Set the initial coordinates
ax = -2;
ay = 2;
bx = 2;
by = -2;

# And the resolution...
xres = 80;
yres = 40;

i = 0;
j = 0;
j < yres ?? (   # Read this as "While j is less than yres do..."
    uy = ay - (ay - by) / yres * j;
    i = 0;
    i < xres  ?? (
        ux = ax + (bx - ax) / xres * i;
        c = mcompute(ux, uy);
        mset[i][j] = c;
        i++
    );
    j++
);

j = 0;
j < yres ?? (
    i = 0;
    i < xres ?? (
        c = mset[i][j];
        # This is a compound conditional, similar to a multiple
        # "if ... else if ... else ..." statement in other languages
        c >= 100 ? print("x") : c > 3 ? print("@") : c > 2 ? print("#") :
            c > 1 ? print("$") : c > 0 ? print(" ");
        i++
    );
    print("\n");
    j++
);


# Function definiton for mcompute()
# This function computes the value of a particular pair of coordinates
@mcompute(
    x = 0;
    y = 0;
    c = 0;
    ((x * x + y * y <= 4) && (c < 100)) ?? (  # Another iterative conditional
        x = (x * x) - (y * y) + $1;  # $1 is function parameter 1
        y = (2 * x * y) + $2;
        c++
    );  # end of iterative conditional
    c;;
)

qsort implementation

#!/usr/local/bin/ee

# x is an array of unsorted values.

x = { 7, 2, 5, 4, 3, 9 };


# calling the qsort function
# notice how the first, second, and third parameters are the input array (x),
# the first element number (0), and the last element ((length of x) - 1).
# However, the forth and fifth arguments, which should be the names of
# functions that swap and compare two elements, are given as function
# definitions.  This is known as first-class anonymous functions.  They aren't
# named (hence "anonymous"), and they can be used as a function argument
# (hence "first class").
#
# A normal function is defined as:
#    @name(expression)
# (Remember that in 2e, an any amount of code is considered an expression.)
# An anonymous function is defined the same way, but without the name:
#    @(expression)
# Normally, in languages such as C, you would define that function somewhere
# and pass the name of it as a parameter to qsort().  But with first class
# functions, you can define the function at the spot where you need it's
# reference.


qsort(
    x, 0, len(x) - 1,
    # swap function definition
    @@(
        enum(c, obj, left, right);
        tmp = $obj[$left];
        $obj[$left] = $obj[$right];
        $obj[$right] = tmp
    ),
    # comparison function definition
    @@(
        enum(ac, obj, left, right);
        $obj[$left] < $obj[$right] ? (-1;;) :
        $obj[$left] > $obj[$right] ? (1;;) : (0;;)
    )
);

i = 0; i < len(x) ?? (
    printf("%d\n", x[i++])
);

# qsort function
# usage:
# qsort(input_array, first_element, last_element, swap_function,
#       compare_function)
# The swap_function and compare_function are user-provided.  swap_function()
# should take three arguments -- the object being sorted (input_array),
# the left element index, and the right element index.
# The compare_function takes the same arguments: object, left, and right.
# It returns a value less than, equal to, or greater than 0 if the left is
# less than, equal to, or greater than the right element, respectively.

@qsort(
    enum(argcount, array, left, right, qswap, qcomp);
    $left >= $right ? (NULL;;) ;
    ($qswap)($array, $left, toint(($left + $right) / 2));
    last = $left;
    i = $left + 1; i <= $right ?? (
        ($qcomp)($array, i, $left) < 0 ? ($qswap)($array, ++last, i);
        i++
    );
    ($qswap)($array, $left, last);
    qsort($array, $left, last - 1, $qswap, $qcomp);
    qsort($array, last + 1, $right, $qswap, $qcomp)
);

# enum function
# usage:
# enum(v1, v2, ...)
# gets passed any number of variables, and will fill them in with integer
# values starting with 0

@enum( i = 1; i <= $0 ?? $i = i++ - 1)