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 skal...@users.sourceforge.net 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 Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language