Just some musings on this:
First, this code:
// NOTE: this will fail if the second argument is named "p"!
// fix as for rev, rev_last!
proc splice[T] : &list[T] * list[T] =
"""
{ // list splice
struct node_t { ?1 elt; void *tail; };
void **p = $1;
while(*p) p = &((node_t*)FLX_VNP(*p))->tail;
*p = $2;
}
"""
;
So we have a problem if the argument $1 happens to be "p".
Here's a solution in another example:
//$ In place list reversal: unsafe!
// second arg is a dummy to make overload work
proc rev[T,PLT=&list[T]] : &list[T] = "_rev($1,(?1*)0);" requires
_iprev_[T,PLT];
body _iprev_[T,PLT]=
"""
static void _rev(?2 plt, ?1*) // second arg is a dummy
{ // in place reversal
struct node_t { ?1 elt; void *tail; };
void *nutail = 0;
void *cur = *plt;
while(cur)
{
void *oldtail = ((node_t*)FLX_VNP(cur))->tail; // save old tail in
temp
((node_t*)FLX_VNP(cur))->tail = nutail; // overwrite current
node tail
nutail = cur; // set new tail to
current
cur = oldtail; // set current to saved
old tail
}
*plt = nutail; // overwrite
}
"""
;
Note PLT=&list[T] in the type arguments. PLT is a dependent type variable.
[Note: not a dependent type!] If you haven't seen these before you can see
the reason: we don't know how to "spell" the type "pointer to list of T" in C++
even if we know the type T, because "list" functor in Felix is translated to an
unknown synthetic name (for each distinct T).
We also need to give a dummy argument in case two distinct T in Felix
reduce to the same C++ type. In that case the list[T]'s will be distinct.
For example:
type A = "int";
type B = "int";
Now, T=A and T=B both translate to C++ type int, but PLT = &list[T] will
still be pointers to distinct structures.
It's ANNOYING to have to split the procedure body from the procedure
call, which requires inventing a name.
Another solution here would be a template:
proc X[T] : T = "Y<?1>($1);" requires Y_template;
header Y_template = "template<class T> void Y(T x) { ... }";
This has the advantage of making C++ handle uniqueness,
note the template is not a polymorphic insertion in Felix
(it is polymorphic in C++ instead).
However there's a MORE annoying case:
fun f: int -> int = "f($1)" requires f_function;
body f_function = """
static int f(int x) {
int z = 0;
for (int i = 0; i<x; ++i) z += int (20.0 * sin (i));
return z;
}
""";
The nasty here is that we have to specify the call to the function,
inventing some name for it, then the body of the function
in a separate definition. It would be nicer to write:
fun f : int -> int = FUNCTIONAL """
int z = 0;
for (int i = 0; i<$1; ++i) z += int (20.0 * sin (i));
return z;
""";
The compiler can:
(a) invent the name of the function
(b) invent a name for the parameter
(c) replace the $1 with that parameter name
(d) generate the call
so as to get back to the original pair of definitions.
I added the word FUNCTIONAL to the syntax just to make
sure the parser recognizes the quoted text is a function
body (not an expression). A similar technique might be
used for procedures (since giving the raw body doesn't
always work .. and also duplicates all the statements on
every call]
--
john skaller
[email protected]
http://felix-lang.org
------------------------------------------------------------------------------
Introducing Performance Central, a new site from SourceForge and
AppDynamics. Performance Central is your source for news, insights,
analysis and resources for efficient Application Performance Management.
Visit us today!
http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
_______________________________________________
Felix-language mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/felix-language