I have change the compiler so arrays are now accessed directly
by the compiler when given the correct index type, but only for
unitsums. For example:

/////////////
var a: int ^ 3 = (1,2,3);
println$ (case 1 of 3) a;

var k = case 1 of 3;
println$ k a;
////////////

now works and is implemented directly in  the compiler. This doesn't break any
code because all current access is being hacked with integers via a C binding
in the library. We have safe and unsafe get methods there. Indexing with the
proper index type is always safe and doesn't require any checks. The library
should be changed to *coerce* an integer argument to the correct type,
eliminating the need for array bounds checks. Instead, the coercion is checked.

The advantage of this is that, for example, parallel access of two arrays
with the same index requires only a single check converting an integer
to a unitsum, instead of two for the two arrays. Some subsequent fiddling
can ensure loops, iterators, etc, are safe by generating indicies of the
correct type instead of hacking it with integers and then using unsafe
get because "we know" the integers are in bounds by design.

The purpose of all this, however, is not to improve performance
although that will be one nice side-effect: the purpose is to allow
multi-dimensional arrays. We already have arrays of arrays, but these
are indexed in two steps:

        a . i . j

If you map some function f over a, f has to accept an argument of the type
of one of the inner arrays, so if you want to map over the matrix of values
you need to make f itself a map of some value translator g. On the other hand
a map over a two dimensional array can use g directly: a two dimensional
array is a linear array with indices of tuple type so the access is like:

        a . (i,j)

instead. 

Now, you may think this is trivial and merely fun notation.

WRONG! [You knew that was coming!!]

Consider an array with index type J where J is a type variable.
We do not know if it is a one, two, three or four dimensional
array BUT WE CAN STILL MAP OVER IT. And fold of course.

This is called array polyadic programming. It means you can write
code which works for arrays of ANY rank. You can test the code on
a simple 2 dimensional case, eg heat transfer in a plate, and then
use the code in a 3 dimensional case, eg heat transfer in a block,
knowing you've tested the code. And without having to write the code
out again with extra loops for the higher rank.

[And I'm going to bet this has some major uses in finance too :]

The way to do this was first developed by Barry Jay in his language
FISh. Jay went on to generalise to all polynomial data functors
(things made of sums and products), and thence to develop the
pattern calculus.

The additional functionality from the array polyadic behaviour
comes from strictly observing the underlying categorical structure
of the types. Which means we need to look at a couple of places
where Felix glosses over some isomorphisms it probably shouldn't.
One is the reinterpretation 

        T * T -> T^2

which is seen in:

        var x = 1,2; // type is int * int = int^2

Actually the types aren't equal, just isomorphic. Similarly
we trick around believing

        T ^ 1  -> T

and I have no idea if Felix gets this one right at all:

        T ^ 0 -> 1

Then there's the other side of arrays. You can regularly
index a tuple and return a uniform type:

        var x = (1, "hello") . case 1 of 2;

You may think x has type string. And if we use case 0
it would be an int. That's why the index has to be a constant.
Right?

That's what happens now except we use an integer constant
instead of a case. If we go to a case we should get the type
right! The correct type of x, that works for ANY index is:

        int + string

this is the dual of the tuple type. We have

        (1, "hello") . (case 1 of 2) = (case 1 of (int + string)) "hello"

in other words a sum constructor an argument. Note carefully
the term not only contains the string as an argument .. it also
RETAINS THE INDEX VALUE.

Why is this important? Because for arrays the result of indexing
should be the same:

        case 2 of 20 (42)

for the third value in an integer array (which happens to be worth 42).

We currently just return 42 when the index is an integer. So not only
is the index "hacked" by using the wrong type, the result has the
wrong type too. We're secretly applying another function to 
get rid of the index and switch the type to the common argument
type (namely int in this case).
 
All these things can be justified. That doesn't mean the compiler
should gloss over them, it means we should correctly define
the "glossing over" bits. For example we have a term in the
compiler "case_arg" which fetches the argument of a sum or
union constructor.

--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to