Basic functionality

The image above shows some simple calculator-like functionality. To understand the picture, you need to know that each cell has three parts: a name, a formula, and a value. The name is colored grey, the formula blue, and the value white. You can only type into the name and formula boxes; the value is calculated automatically from the other information.

Like a typical spreadsheet, Explicans has automatic recalculation. The picture above is like the previous one except the value for b was changed from 7 to 3. Because c and d depend on b, these values were updated automatically.

The previous images had the cells arranged horizontally. In this image, File->Flip has been activated, so the cells are now arranged vertically. There is no difference in meaning, but allowing cells to be arranged both vertically and horizontally lets the user better organize a worksheet.

Arrays

Explicans' basic data type is the array. You can create an array by typing in array(n) into a formula. In the above screenshot, an array of length 4 has been created. Note the similarity between the array created and the top level cells—-an entire explicans program is just an array of cells.

Inside the array, you can see that formulas are calculated like before. In the screenshot above for instance, a+5 evaluates to 10 because a was given the value 5 at top-level.

The screenshot above shows that arrays, once created, are first-class objects. Cell a is the array "hello"/"world"/"!". Cell b refers to cell a in its formula, so all three elements of that array shows up. Furthermore, an array can be edited, so in b, the "world" is overwritten to be "there".

Note, however, that Explicans is fully functionaly. The array a wasn't modified. Cell c refers to a and gets the original "hello"/"world"/"!". However cell d refers to b and gets the new version "hello"/"there"/"!".

Instead of modification, Explicans follows the rule that specific beats general. The second element of b should be "world" because a has world there, and b's formula is "a". However, the second element should also be "there" because the user has typed that in as the formula. This conflict is resolved in favor of the more specific rule, so the second element of b is "there", not "world".

This screenshots looks a bit complicated (I need to work on the graphics) but illustrates two things. First, an array can contain another array. There is no way to run out of space visually—-stuff will just get moved down/right to make room. Also there is no conceptual limit on how many levels of nesting is possible.

Second, an object outside of an array can refer to something inside by using the colon (":") operator. In the picture above, a is an array of length 3 at top level. Inside a is another array of length 2, called a1. And inside a1 is the number 17, called a11. At top level, a:a1:a11 evaluates to 17, and thus d equals 1+17*2 = 35. If you're interested, look at the other formulas and see if the resulting values make sense.

Operations on Arrays

This screenshow shows the the sequence operator "..". For right now, it just creates an array by filling in the numbers between two other numbers. So 1..3 in the first cell creates an array of length 3 and populates it with the numbers 1, 2, 3.

Also, there are tons of empty space in these examples, because the graphics aren't good. Ideally, any blank elements (like most of the name and formula boxes) should be hidden, which will allow for a much higher information density. So when you're looking at these screenshots, just imagine that I have already done that. :)

The screenshot above shows that if you use basic arithmetic operations on arrays, they are automatically expanded to do the same thing to each element. Thus b = a+4 are the values 5, 6, 7, and 8.

More technically, Explicans has a simple type system in which there are two basic types of objects: scalars and non-scalars. Numbers and strings are scalars, but arrays are non-scalars. Each argument of an operations and function is typed, so when an array is passed to a function where the function is expecting a scalar, the function is repeated for each element of the array.

The screenshot above shows what happens when array and scalar arithmetic is mixed. a is an array but b is a scalar. a+b is an array, where b has been upconverted to an array by repetition. That is why c is the numbers 11, 12, 13, and 14.

Array Indexing and Methods

This screenshot shows C-style indexing into arrays. It also supports Python-style negative indexing, so that a[-1] means the last element of array a.

This screenshot shows some basic methods of Explicans' arrays. To access a method, use the C-style operator ".". Note this is different than the lookup operator ":", so methods cannot be confused with elements of the list.

In the example, the methods sort and reverse are shown. Like in Ruby, there is no need for parentheses when calling a method with no arguments. Of course everything is still automatically recalculating, including the sort. This is already something you can't do in, say, Excel, where the notion of a sort cannot be expressed in the Excel language itself.

Array Boolean Operations

As the screenshot above shows, the basic numerical comparisons like "=" and ">" are scalar operations, as is the or operator. That means they are automatically scaled up to operate on arrays also. Their output is the boolean values of TRUE or FALSE, which are considered scalars along with strings and numbers.

This screenshot shows the "where" operator, which takes two arrays and returns the elements of the first array where the second array is TRUE (if you pass it something other than booleans you get an error). Thus a where a > 5 does what it looks like it does, even though there's really an array of booleans underneath.

Relative References

Explicans, unlike Excel, doesn't have any special syntax for relative references. However, prev always refers to the previous cell in the array, and next refers to the next cell. Also, any object in a cell (i.e. a located object) automatically has the methods next, prev, and up. Up takes no arguments, but next and prev take the number of cells up or down.

me refers to the current object, so me.next(2) means the cell two locations down. As in the screenshot, me.up.next(2) means go up to the parent array, and move two cells down. However, the actual value of me is blank while the formula is being evaluated, so you can't actually say me+1 or something like that.

Column Formulas

In case you were wondering what that grey and blue bar above arrays was for, this screenshot demonstrates that they were for column formulas. Column formulas are evaluated just like any other formula, and their value is set to the value of the array. However, the relative reference operations such as next and prev have a different meaning inside column formulas.

For instance, inside a column formula, prev means the very same array, but shifted up one. Thus in b, each cell is 1 because the first cell is 1 and the column formula is prev. The meaning of prev was chosen this way because it mimics what would happen if you wrote prev in every formula of the array.

Similarly, the next array c counts from 1 because the column formula is prev+1.

The screenshot above shows how the Fibonacci numbers can be computed. The column formula (partially occluded) is me.prev(1)+me.prev(2), meaning each element is the one one element before plus the one two elements before. (The formula could also have been written prev + me.prev(2)).

Note we have done something pretty cool IMHO with this example. This spreadsheet computes the nth Fibonacci number, where n can be updated at will. Furthermore it will graphically expand/contract based on n to show the complete calculation.

Tables

So far we've only seen (one dimensional) arrays and basic scalar data types like numbers. This screenshot shows another type, the table. Future non-scalars that could be added include functions, graphs, etc.

Tables allow for convenient calculation like the way traditional spreadsheets work. Unlike arrays, however, tables cannot contain non-scalar values. This would get too visually confusing if a table contained another array or table.

Each table can be thought of as a bunch of arrays, and the screenshot shows how an individual row or column in the table can be referred to using the lookup operator ":". The screenshot also shows some column formulas in the table. It should also be possible to modify individual rows in the table, just as it's possible for arrays. The semantics of this is actually implemented, but it's not possible in the interface currently.