I wrote:

> So now, the BIG one. First, understand that a union like:
> 
>       union list = | Empty | Cons of int * list
> 
> is represented by a packed pointer:
> 
>       0 --> Empty
>       1 + pointer --> Cons

No longer, now it is:

> But now, we want a new representation:
> 
>       0 --> NULL
>       other -> a real pointer
> 
> This is of course your usual C pointer. 

Now, it is implemented. list and opt type are both affected.
This means, for example, the representation

        opt[int]

is either NULL or a pointer to a heap allocated int. 

OTOH I **think** that

        opt[&int]

is a ALSO a pointer to an int (not necessarily heap allocated).

The type system is used to determine which of the two
representations is used.  This should be the case for all
variant representations (including VR_uctor, the standard one:
the pointer may be EITHER a pointer to a heap allocated
object OR the original pointer if that's the data types.
Note functions are pointers to C++ class objects so they're
also pointers.

I will have to triple check all this (because a mistake will lead
to weird behaviour and core dumps .. but possibly only in
corner cases).

If I'm right, then

        opt[&int]

is already a possibly null pointer to int. So actually

        union ptr [T] = | nullptr | Ptr of &T;

differs only in that the constant is called nullptr, and the T given is the
type pointed at.

To make this look pretty we need to allow "@" as an identifier,
and then:

        union @[T] = | nullptr | Ptr of &T;

        fun deref[T] (px:@[T]) = let Ptr ?p = px in *p;

The latter will crash your program with a match failure if px is nullptr.

        var px = nullptr[int];
        var x = *px; // match failure!


We can also do:

        typedef ptr[T] = &T;
        typedef cptr[T] = @[T];

        ctor[T] cptr[T]: &T => @[T] = "$1";
        ctor[T] ptr[T] (cp:@T) => let Ptr ?p = cp in p;

although the latter is a pain because it just gives an assert failure instead 
of a 
null pointer failure .. but at least it has a chance of giving a source code 
reference
to the C++ code.

These converters let you convert between @T and &T safely. As is usual in Felix
you will HAVE to do that to get your pointers to agree with function signatures.

        (px.ptr, py.cptr).f.ptr

will call f: &T * @T -> @T

The pain is minimised, we can still get null pointer errors, but now they 
should be
detected by Felix/C++ code instead of OS detected bus errors.

The bottom line here is that a TRICK representation artefact enables us to do 
the checking IN FELIX instead of building it into the compiler. The 
representation also
has the side effect of making other types faster (opt and list mainly).

BTW: in the end this might have to go into the compiler, unless I can find a way
to track source references in Felix properly. There is a primitive to do this,
but it never works because it is always used in a function, and so just tells
the source location of the function, not the caller. In the above cases
the constructor ptr and defer operator .. whether or not they're inlined.
At least the C++ reference refers to the actual position in your program.

--
john skaller
skal...@users.sourceforge.net





------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to