diff --git a/TODO b/TODO
index d10d6516223cdb148f0dc90bd4dc977b15c8440e..c8bf75b10471020ceeab4c47e1b06cf17679275c 100644
--- a/TODO
+++ b/TODO
@@ -24,6 +24,7 @@ WISHLIST JWu
 - convolutand must not be defined over full energy range
 - mfj remove redundant doc lines
 - dp output for #spec>1 is obfuscated
+- coord name algebra
 
 - customization
   - frida.ini location via -D 
diff --git a/pub/src/curve.cpp b/pub/src/curve.cpp
index b7c5ced2848f7e23f7b1eb929920a3cd5255f621..6d081c10fd5f674f71b44f553a401fd6be571ba1 100644
--- a/pub/src/curve.cpp
+++ b/pub/src/curve.cpp
@@ -175,6 +175,7 @@ vector<string> COlc::pInfo() const
     vector<string> ret;
     // file-wide info:
     ret.push_back( expr );
+    ret.push_back( T->tree_info() );
     if( kd!=-1 )
         ret.push_back( "refers to data:  " + strg(kd) );
     if( kconv!=-1 )
diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp
index 0e1592b57fdc11189f31e45ed3f9463cd90dd228..96eb3dbee5af34fbc19b35f641642802f86cf27e 100644
--- a/pub/src/expr.cpp
+++ b/pub/src/expr.cpp
@@ -955,9 +955,9 @@ string CTree::tree_info() const
 {
     string ret;
     if       ( typ == _OP ) {
-        ret = "op[";
+        ret = fun->txt + "(";
         for ( uint iarg=0; iarg<narg; ++iarg )
-            ret += arg[iarg]->tree_info() + (iarg<narg-1 ? "," : "]" );
+            ret += arg[iarg]->tree_info() + (iarg<narg-1 ? "," : ")" );
         return ret;
     }
     else if ( typ == _CONV )
diff --git a/pub/src/func.cpp b/pub/src/func.cpp
index 0dd4e0fee72552a94124a99b3ddb5b3c4dfb50a7..4c5c17b2d3a2b1ed1cf3d798d0b9a69e4896ac43 100644
--- a/pub/src/func.cpp
+++ b/pub/src/func.cpp
@@ -145,13 +145,6 @@ double func_ran (double v, double a) {
     // a random number between v and a :
     return func_min(v,a) + (func_max(v,a)-func_min(v,a))*NRNG::uniform(); }
 
-double func_in (double d1, vector<double> v2)
-{
-    for( uint i=0; i<v2.size(); ++i )
-        if( d1==v2[i] ) return 1.;
-    return 0.;
-}
-
 //**************************************************************************//
 //*   Functions of three arguments                                         *//
 //**************************************************************************//
@@ -169,102 +162,6 @@ double func_cauchy2 (double x, double p, double w) {
     return w==0 ? 0 : 2*w/twopi*(1.0/(SQR(x-p)+SQR(w))+1.0/(SQR(x+p)+SQR(w)));
 }
 
-//**************************************************************************//
-//*   Function registration and retrieval                                  *//
-//**************************************************************************//
-
-namespace NFunctions { // internals:
-    map<string,CFunc> fmap;
-};
-
-void NFunctions::Register(void) {
-
-// mon-op
-    fmap.insert(make_pair(string("!"),    CFunc("!",    func_not)));
-
-// bin-op  
-    fmap.insert(make_pair(string("+"),    CFunc("+",    func_add)));
-    fmap.insert(make_pair(string("-"),    CFunc("-",    func_sub)));
-    fmap.insert(make_pair(string("*"),    CFunc("*",    func_mul)));
-    fmap.insert(make_pair(string("/"),    CFunc("/",    func_div)));
-    fmap.insert(make_pair(string("^"),    CFunc("^",    func_pow)));
-  
-    fmap.insert(make_pair(string("=="),   CFunc("==",  func_eq)));
-    fmap.insert(make_pair(string("!="),   CFunc("!=",  func_ne)));
-    fmap.insert(make_pair(string(">"),    CFunc(">",   func_gt)));
-    fmap.insert(make_pair(string(">="),   CFunc(">=",  func_ge)));
-    fmap.insert(make_pair(string("<"),    CFunc("<",   func_lt)));
-    fmap.insert(make_pair(string("<="),   CFunc("<=",  func_le)));
-    fmap.insert(make_pair(string("&&"),   CFunc("&&",  func_and)));
-    fmap.insert(make_pair(string("||"),   CFunc("||",  func_or)));
-    fmap.insert(make_pair(string("xor"),  CFunc("xor", func_xor)));
-    fmap.insert(make_pair(string("mod"),  CFunc("mod", func_mod)));
-    fmap.insert(make_pair(string("idiv"), CFunc("mod", func_idiv)));
-    fmap.insert(make_pair(string("over"), CFunc("over",func_over)));
-
-// ter-op    
-    fmap.insert(make_pair(string("?:"),   CFunc("?:",   func_condass)));
-
-// f( 1 arg )
-    fmap.insert(make_pair(string("0-"),   CFunc("0-",   func_neg)));
-    fmap.insert(make_pair(string("ln"),   CFunc("ln",   func_ln)));
-    fmap.insert(make_pair(string("lg"),   CFunc("lg",   func_lg)));
-    fmap.insert(make_pair(string("sqrt"), CFunc("sqrt", func_sqrt)));
-    fmap.insert(make_pair(string("abs"),  CFunc("abs",  func_abs)));
-    fmap.insert(make_pair(string("exp"),  CFunc("exp",  func_exp)));
-    fmap.insert(make_pair(string("sin"),  CFunc("sin",  func_sin)));
-    fmap.insert(make_pair(string("cos"),  CFunc("cos",  func_cos)));
-    fmap.insert(make_pair(string("tan"),  CFunc("tan",  func_tan)));
-    fmap.insert(make_pair(string("cot"),  CFunc("cot",  func_cot)));
-    fmap.insert(make_pair(string("sind"), CFunc("sind", func_sind)));
-    fmap.insert(make_pair(string("cosd"), CFunc("cosd", func_cosd)));
-    fmap.insert(make_pair(string("tand"), CFunc("tand", func_tand)));
-    fmap.insert(make_pair(string("cotd"), CFunc("cotd", func_cotd)));
-    fmap.insert(make_pair(string("asin"), CFunc("asin", func_asin)));
-    fmap.insert(make_pair(string("acos"), CFunc("acos", func_acos)));
-    fmap.insert(make_pair(string("atan"), CFunc("atan", func_atan)));
-    fmap.insert(make_pair(string("acot"), CFunc("acot", func_acot)));
-    fmap.insert(make_pair(string("asind"),CFunc("asind",func_asind)));
-    fmap.insert(make_pair(string("acosd"),CFunc("acosd",func_acosd)));
-    fmap.insert(make_pair(string("atand"),CFunc("atand",func_atand)));
-    fmap.insert(make_pair(string("acotd"),CFunc("acotd",func_acotd)));
-    fmap.insert(make_pair(string("gamma"),CFunc("gamma",func_gamma)));
-    fmap.insert(make_pair(string("erfP"), CFunc("erfP", func_erfP)));
-    fmap.insert(make_pair(string("erfQ"), CFunc("erfQ", func_erfQ)));
-    fmap.insert(make_pair(string("erf"),  CFunc("erf",  func_erf)));
-    fmap.insert(make_pair(string("erfc"), CFunc("erfc", func_erfc)));
-    fmap.insert(make_pair(string("sinc"), CFunc("sinc", func_sinc)));
-    fmap.insert(make_pair(string("ceil"), CFunc("ceil", func_ceil)));
-    fmap.insert(make_pair(string("floor"),CFunc("floor",func_floor)));
-    fmap.insert(make_pair(string("nint"), CFunc("nint", func_nint)));
-
-// f ( 2arg )
-    fmap.insert(make_pair(string("min"),  CFunc("min",  func_min)));
-    fmap.insert(make_pair(string("max"),  CFunc("max",  func_max)));
-    fmap.insert(make_pair(string("gauss"),CFunc("gauss",  func_gauss)));
-    fmap.insert(make_pair(string("gaussnn"),CFunc("gaussnn",  func_gaussnn)));
-    fmap.insert(make_pair(string("gnn"),    CFunc("gaussnn",  func_gaussnn)));
-    fmap.insert(make_pair(string("cauchy"),CFunc("cauchy",  func_cauchy)));
-    fmap.insert(make_pair(string("kwwc"), CFunc("kwwc",func_kwwc)));
-    fmap.insert(make_pair(string("kwws"), CFunc("kwws",func_kwws)));
-    fmap.insert(make_pair(string("skww"), CFunc("skww",func_skww)));
-
-    fmap.insert(make_pair(string("ran"),  CFunc("ran",  func_ran)));
-
-    fmap.insert(make_pair(string("q4w"),  CFunc("ran",  func_q4w)));
-    fmap.insert(make_pair(string("cauchy2"),  CFunc("cauchy2",  func_cauchy2)));
-}
-
-CFunc* NFunctions::find(string s)
-{
-    // printf( "find\n" );
-    map<string,CFunc>::iterator pos;
-    if ((pos = fmap.find(s)) == (fmap.end())) return 0;
-    // printf( "/find\n" );
-    return &(pos->second);
-}
-
-
 //**************************************************************************//
 //*   Coordinate concatenation                                             *//
 //**************************************************************************//
@@ -272,30 +169,17 @@ CFunc* NFunctions::find(string s)
 CCoord CFunc::coord( CCoord *co1 ) const
 {
     CCoord co = *co1;
-    if        (s=="1/") {
-        co.name = "1/" + co1->name;
-        co.unit = co1->unit=="" ? "" : "(" + co1->unit + ")^-1";	
-    } else if (s=="0-") {
+    if (txt=="0-") {
         co.name = "-" + co1->name;
-    } else if (s=="e^") {
-        co.name = "e^" + co1->name;
-    } else if (s=="10^") {
-        co.name = "10^" + co1->name;
-    } else if (s=="ln") {
+    } else if (txt=="ln") {
         co.name = "ln " + co1->name;
-    } else if (s=="lg") {
+    } else if (txt=="lg") {
         co.name = "lg " + co1->name;
-    } else if (s=="^2") {
-        co.name = "(" + co1->name + ")^2";
-        co.unit = co1->unit=="" ? "" : "(" + co1->unit + ")^2";	
-    } else if (s=="sqrt") {
+    } else if (txt=="sqrt") {
         co.name = "sqrt (" + co1->name + ")";
         co.unit = co1->unit=="" ? "" : "(" + co1->unit + ")^1/2";	
-    } else if (s=="abs") {
-        co.name = "abs (" + co1->name + ")";
-    } else if (s=="") {
     } else {
-        co.name = s + "(" + co1->name + ")";        
+        co.name = txt + "(" + co1->name + ")";        
     }
     return co;
 }
@@ -304,14 +188,14 @@ CCoord CFunc::coord( class CCoord *co1, class CCoord *co2 ) const
 {
     CCoord co = *co1;
 
-    if ( s=="+" || s=="-" ) {
+    if ( txt=="+" || txt=="-" ) {
         if( co1->name==co2->name ){
             if( co1->unit!=co2->unit )
                 throw string( "same coordinate name and different units" 
                               " in additive operation" );
             co = *co1;
         } else {
-            co.name = co1->name + s + co2->name;
+            co.name = co1->name + txt + co2->name;
             if ( co1->unit=="" )
                 co.unit = "";
             else if ( co2->unit!="" && co2->unit!=co1->unit) {
@@ -321,17 +205,17 @@ CCoord CFunc::coord( class CCoord *co1, class CCoord *co2 ) const
             } else
                 co.unit = co1->unit;
         }
-    } else if ( s=="*" || s=="/" ) {
-        co.name = co1->name + s + co2->name;
+    } else if ( txt=="*" || txt=="/" ) {
+        co.name = co1->name + txt + co2->name;
         if     ( co1->unit!="" && co2->unit!="" )
-            co.unit = co1->unit + s + co2->unit;
+            co.unit = co1->unit + txt + co2->unit;
         else if( co1->unit!="" )
             co.unit = co1->unit;
         else if( co2->unit!="" )
-            co.unit = s=="*" ? co2->unit : "1/(" + co2->unit + ")";
+            co.unit = txt=="*" ? co2->unit : "1/(" + co2->unit + ")";
         else
             co.unit = "";
-    } else if ( s=="^" ) {
+    } else if ( txt=="^" ) {
         if (co2->unit != "") {
             cout << "? exponent is not dimensionless\n";
         }
@@ -347,3 +231,101 @@ CCoord CFunc::coord( class CCoord *co1, class CCoord *co2, class CCoord *co3 )
     CCoord co = *co2;
     return co;
 }
+
+//**************************************************************************//
+//*   Function registration and retrieval                                  *//
+//**************************************************************************//
+
+namespace NFunctions { // internals:
+    map<string,CFunc> fmap;
+};
+
+CFunc* NFunctions::find( string key )
+{
+    map<string,CFunc>::iterator pos;
+    if ((pos = fmap.find(key)) == (fmap.end())) return 0;
+    return &(pos->second);
+}
+
+void CFunc::register_me( void *_fmap ) const
+{
+    ((map<string,CFunc>*)_fmap)->insert( make_pair( txt, *this ) );
+}
+
+void NFunctions::Register(void) {
+
+// mon-op
+    CFunc( "!",    func_not    ).register_me( &fmap );
+
+// bin-op  
+    CFunc( "+",    func_add    ).register_me( &fmap );
+    CFunc( "-",    func_sub    ).register_me( &fmap );
+    CFunc( "*",    func_mul    ).register_me( &fmap );
+    CFunc( "/",    func_div    ).register_me( &fmap );
+    CFunc( "^",    func_pow    ).register_me( &fmap );
+  
+    CFunc( "==",  func_eq      ).register_me( &fmap );
+    CFunc( "!=",  func_ne      ).register_me( &fmap );
+    CFunc( ">",   func_gt      ).register_me( &fmap );
+    CFunc( ">=",  func_ge      ).register_me( &fmap );
+    CFunc( "<",   func_lt      ).register_me( &fmap );
+    CFunc( "<=",  func_le      ).register_me( &fmap );
+    CFunc( "&&",  func_and     ).register_me( &fmap );
+    CFunc( "||",  func_or      ).register_me( &fmap );
+    CFunc( "xor", func_xor     ).register_me( &fmap );
+    CFunc( "mod", func_mod     ).register_me( &fmap );
+    CFunc( "mod", func_idiv    ).register_me( &fmap );
+    CFunc( "over",func_over    ).register_me( &fmap );
+
+// ter-op    
+    CFunc( "?:",   func_condass).register_me( &fmap );
+
+// f( 1 arg )
+    CFunc( "0-",   func_neg    ).register_me( &fmap );
+    CFunc( "ln",   func_ln     ).register_me( &fmap );
+    CFunc( "lg",   func_lg     ).register_me( &fmap );
+    CFunc( "sqrt", func_sqrt   ).register_me( &fmap );
+    CFunc( "abs",  func_abs    ).register_me( &fmap );
+    CFunc( "exp",  func_exp    ).register_me( &fmap );
+    CFunc( "sin",  func_sin    ).register_me( &fmap );
+    CFunc( "cos",  func_cos    ).register_me( &fmap );
+    CFunc( "tan",  func_tan    ).register_me( &fmap );
+    CFunc( "cot",  func_cot    ).register_me( &fmap );
+    CFunc( "sind", func_sind   ).register_me( &fmap );
+    CFunc( "cosd", func_cosd   ).register_me( &fmap );
+    CFunc( "tand", func_tand   ).register_me( &fmap );
+    CFunc( "cotd", func_cotd   ).register_me( &fmap );
+    CFunc( "asin", func_asin   ).register_me( &fmap );
+    CFunc( "acos", func_acos   ).register_me( &fmap );
+    CFunc( "atan", func_atan   ).register_me( &fmap );
+    CFunc( "acot", func_acot   ).register_me( &fmap );
+    CFunc( "asind",func_asind  ).register_me( &fmap );
+    CFunc( "acosd",func_acosd  ).register_me( &fmap );
+    CFunc( "atand",func_atand  ).register_me( &fmap );
+    CFunc( "acotd",func_acotd  ).register_me( &fmap );
+    CFunc( "gamma",func_gamma  ).register_me( &fmap );
+    CFunc( "erfP", func_erfP   ).register_me( &fmap );
+    CFunc( "erfQ", func_erfQ   ).register_me( &fmap );
+    CFunc( "erf",  func_erf    ).register_me( &fmap );
+    CFunc( "erfc", func_erfc   ).register_me( &fmap );
+    CFunc( "sinc", func_sinc   ).register_me( &fmap );
+    CFunc( "ceil", func_ceil   ).register_me( &fmap );
+    CFunc( "floor",func_floor  ).register_me( &fmap );
+    CFunc( "nint", func_nint   ).register_me( &fmap );
+
+// f(2 args)
+    CFunc( "min",  func_min    ).register_me( &fmap );
+    CFunc( "max",  func_max    ).register_me( &fmap );
+    CFunc( "gauss",  func_gauss).register_me( &fmap );
+    CFunc( "gaussnn",  func_gaussnn ).register_me( &fmap );
+    CFunc( "gaussnn",  func_gaussnn ).register_me( &fmap );
+    CFunc( "cauchy",  func_cauchy ).register_me( &fmap );
+    CFunc( "kwwc",func_kwwc    ).register_me( &fmap );
+    CFunc( "kwws",func_kwws    ).register_me( &fmap );
+    CFunc( "skww",func_skww    ).register_me( &fmap );
+
+    CFunc( "ran",  func_ran    ).register_me( &fmap );
+
+    CFunc( "q4w",  func_q4w    ).register_me( &fmap );
+    CFunc( "cauchy2",  func_cauchy2 ).register_me( &fmap );
+}
diff --git a/pub/src/func.h b/pub/src/func.h
index 56b78016bf42a889de72751ade0460a81e1f3d1d..4a7b92e860d3b98c1fc3234d3b329ac66858daef 100644
--- a/pub/src/func.h
+++ b/pub/src/func.h
@@ -1,33 +1,31 @@
 typedef double (*func_f1) (double);
 typedef double (*func_f2) (double, double);
 typedef double (*func_f3) (double, double, double);
-typedef double (*func_f2tv) (double, vector<double>);
 
 class CFunc { // public (short) interface => TAKE CARE
  public:
-    string s;
+    string txt;
     int narg;
     func_f1 f1;
     func_f2 f2;
     func_f3 f3;
-    func_f2tv f2tv;
     class CCoord coord( class CCoord *co ) const;
     class CCoord coord( class CCoord *co1, class CCoord *co2 ) const;
     class CCoord coord( class CCoord *co1, class CCoord *co2,
                         class CCoord *co3 ) const;
-    CFunc( string _s, func_f1 _f1 )
-        : s(_s), narg(1), f1(_f1) {};
-    CFunc( string _s, func_f2 _f2 )
-        : s(_s), narg(2), f2(_f2) {};
-    CFunc( string _s, func_f3 _f3 )
-        : s(_s), narg(3), f3(_f3) {};
-    CFunc( string _s, func_f2tv _f2tv )
-        : s(_s), narg(2), f2tv(_f2tv) {};
+    CFunc( string _txt, func_f1 _f1 )
+        : txt(_txt), narg(1), f1(_f1) {};
+    CFunc( string _txt, func_f2 _f2 )
+        : txt(_txt), narg(2), f2(_f2) {};
+    CFunc( string _txt, func_f3 _f3 )
+        : txt(_txt), narg(3), f3(_f3) {};
+
+    void register_me( void *fmap ) const;
 };
 
 namespace NFunctions { // public (short) interface
     void Register(void);
-    CFunc* find(string nam);
+    CFunc* find( string nam );
 };
 
 extern double func_not(double);