I have been playing with the new naming system.

It works kinda like this:

//PRIMITIVE 8473 INSTANCE 83822: string
typedef ::std::basic_string<char> _a8473t_83822;
typedef int _us2;

//PRIMITIVE 3795 INSTANCE 83825: int
//typedef int int;

//TYPE 83827: string^2
typedef _at<_a8473t_83822,2> _at83827;

//TYPE 83828: string * list[string]
typedef _tt2<_a8473t_83822,void*> _tt83828;

//TYPE 83829: list[string]^2
typedef _at<void*,2> _at83829;

//PRIMITIVE 5809 INSTANCE 83830: ostream
typedef ::std::ostream* _a5809t_83830;

//TYPE 83831: ostream * string
typedef _tt2<_a5809t_83830,_a8473t_83822> _tt83831;

...

//TYPE 83827: string^2
template <> struct _at<_a8473t_83822,2> {
  static size_t const len = 2;
  typedef _a8473t_83822 element_type;
  _a8473t_83822 data[2];
  _at<_a8473t_83822,2>() {}
  _at<_a8473t_83822,2>(_a8473t_83822 a0, _a8473t_83822 a1) {
    data[0] = a0;
    data[1] = a1;
  }
};

//TYPE 83828: string * list[string]
template <> struct _tt2<_a8473t_83822,void*> {
  _a8473t_83822 mem_0;
  void* mem_1;
  _tt2<_a8473t_83822,void*>(){}
  _tt2<_a8473t_83822,void*>(_a8473t_83822 a0, void* a1):
    mem_0(a0), mem_1(a1){}
};

Basically, we have a template _tt2<X,Y> for tuple names,
we never define it generally, but we do specialise it.
Similarly _at for array types, _ft for function types.

The executable code continues to use the aliases (typedefs).
Each specialisation's argument are also using the aliases,
the each appearance of a structure name only uses one level
of template syntactically.

The idea here is that any Felix code needing, say, an
array of two strings or a list of ints or whatever will name
them the same for the purpose of external linkage,
so C++ functions can be linked across translation units
and DLL boundaries using C++ type safe linkage.

Without this, it is hard to "export" a function that takes
a structurally typed value (tuple, array, variant, etc):
we can put the argument type in a header file easily,
but the name will be 

_a8473t_83822

or something which could change with any minor modification
to any part of the library, so we cannot then create a Felix binding
to this C name in out importation script.

A name like:

        _tt2<string, int>

however is deterministic, based only on the names of the tuple
argument types.

nominally typed enties (structs for example) can be given their Felix
names as their C names. And we can wrap such names in namespaces
corresponding to the Felix class containing them to ensure they're unique.

but I forgot about abstract names:

type metres  = "int";
type feet = "int";

and now metres * metres and feet * feet both have type:

  _tt<int, int> // actually _at<int,2>

This actually saves on duplicated definitions but it makes it impossible
to export both

        f of (metres * metres)
        f of (feet * feet)

in C++ since the linkage names are

        f (int, int)

in both cases. In fact the problem has nothing at all to do with tuples!!!!
It's a problem for

        export fun f(x:metres)=> ...
        export fun f(x:feet)=>

too. So, we can create, for primitives, a special tag name:

        struct metres;
        struct feet;

and use that for the tuple definition instead of "int": the actual
type used in the definition is still int, just the name of the tuple
type itself uses the tag name (the tag name is never defined).

this is cool because it solves another problem: what do we name
a polymorphic type instance?

Clearly from

        type vect[T] = "::std::vector<?1>";

we need to generate a tag name like this:

        template <typename T> struct vect;

Again, this is not a type. It's just a unique name
used when defining the actual type.

However, this got me thinking: how does Felix actually handle
recursive types now?

The distinction between the tag/structure names and the actual types
is that the tag names can put a dummy where recursion occurs:
in fact the internal Felix representation uses a weird encoding
for fixpoints already, a list is like:

        1 + T * (fix -2)

where the -2 means the fixpoint binder is up two levels in the term:

        (1 + T * x) as x

One level for the * and another for the +. The obvious implementation for
tags is just

        _fix<2>

The idea was the definitions of types could do this:

        struct list {
                ..
                list *next;
        };

and it would work because C supports types recursion via incomplete types.
The BIG problem with C++ templates is that they don't: you can't give a template
class definition an incomplete type argument, even if it is only used as the 
target
of a pointer in the definition. [This is a serious BUG in C++ and is half the 
reason
Felix exists in the first place. It's intolerable]

However, Felix hardly every uses this. The actual list definition uses a void *
and casts. It does this because that's how variants (sums, unions, etc) are
encoded: we use universal types and casts on usage.

It does use it sometimes though:

fun f(x:int): (int -> t) as t=> f;

//TYPE 79711: (int -> fix-1_a as fix-1_a )
struct _ft79711 {
  typedef _ft79711* rettype;
  typedef int argtype;
  virtual _ft79711* apply(int const &)=0;
  virtual _ft79711 *clone()=0;
  virtual ~_ft79711(){};
};


Another example:

var x = (1,&x);

//TYPE 79705: (int * &fix-2_a as fix-2_a )
struct _tt79705 {
  int mem_0;
  _tt79705* mem_1;
  _tt79705(){}
  _tt79705(int a0, _tt79705* a1):
    mem_0(a0), mem_1(a1){}
};

These show that it is NOT enough to just use a template
to generate a tuple .. in the tuple case here, the type of
the second argument is a pointer to the structure type.

BTW: this type is USEFUL!!! It's an infinite list.
And those things can be used in iterators (streams) to good effect.

The tuple above, however can be defined by

template<> struct _tt<int, fix<2>*>
{
  ...
}

and the name is canonical (unlike _tt79705)!!

So unfortunately .. we cannot use template definitions for tuples
(or functions or arrays or whatever, which is very sad).

--
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