I'm attempting to solve the array access problem with a new operator:

        a &. i <- v;

This operator has a higher precedence than operator . so

        a &. b . c . d --> (a &. b) . c . d 

The idea is that this can be used as so:

        var a = 1,2,3;
        a &. 1 <- 42;


which in this case means exactly the same as:

        (&a) . i <- 42;

The choice is for symmetry with 

        p *. i

meaning the same as

        (*p).i

which in C would be written p -> i.

The reason for this new operator is so that these can be made to work:

        var ca = array_alloc[int] (3);
        ca &. 0 <- 1;
        ca &. 1 <- 2;
        ca &. 2 <- 3;

        var va = varray (1,2,3);
        va &. 1 <- 42;

        var da = darray (1,2,3);
        da &. 1 <- 42;

In all these cases you can NOT write

        (&a) . 1 <- 42;

and expect it to work, because that's just taking the address
of the array variable. What we want instead is to get the address
of an element in an array.

There are some issues. One is that this cannot work for
a bit array (because bits aren't addressable). set and 
get work for a bitarray. It also can't work for any array type
that "hides" its elements, i.e. doesn't put them in a store.
A Judy1 array is an example of BOTH these things:
its both a bit array, and also, there's no store for the bits.

There's another problem. This operator breaks abstraction
and safety by allowing a pointer to leak. The pointer may
dangle if the array is modified (darray) or deleted.

So there's a requirement to use such a pointer immediately.
Lacking linear types, we cannot enforce a one use policy,
but actually that's NOT a requirement.

With this notation, assignment of arrays with = is deprecated.
So do not write:

        a . 1 = 42;

but instead write:

        a &. 1 <- 42;

However, we're not finished. This has to work for structures (struct,
cstruct, tuple, record) as well. Then, we can get rid of the assignment
hack entirely. We can go back to:

        a = b ----> (&a) <- b

and enforce it: the LHS of an assignment has to be a whole variable name.

To make this work:

        var r = (a=1,b=2); // record
        r &. a <- 42;

has to work too. Unfortunately this has to be done by the compiler.
The array definition:

        a &. i --> (&a) . i

is exactly what we want for structures, but here i is a field name,
and there's no way to generalise over field names in the library.

There's actually a deeper problem here: Felix has no way to add
offsets. Array and structure projections are just offsets.
C++ cannot do this either despite me harassing the committee.

Basically given

        (a &. i) . j . j

we would like to calculate:

        a &. (i . j . k)

i.e. compose the offsets by adding them. We might do that for field
names if we could figure their types. There's no way to do that
for array indicies at the moment because they're either plain
old integers, or, just as bad, they're cases of compact linear
types like 3. Neither of these is an *actual* projection function.
A real projection function would go something like:

        N -> int ^ N -> int

and we need the model something like:

        proj 1 of int^N
        proj "a" of (a:int, b:int)



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




------------------------------------------------------------------------------
The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, 
is your hub for all things parallel software development, from weekly thought 
leadership blogs to news, videos, case studies, tutorials, tech docs, 
whitepapers, evaluation guides, and opinion stories. Check out the most 
recent posts - join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to