Index: src/CodeTools/ResolvProtoDump.cc
===================================================================
--- src/CodeTools/ResolvProtoDump.cc	(revision 6e9ffd1ac70caa919cad72a6f42350903f28d19b)
+++ src/CodeTools/ResolvProtoDump.cc	(revision ec71a50975a9d7697d5de0e27072837d6203d86d)
@@ -196,12 +196,20 @@
 			}
 			
-			// default to just name
-			ss << pre << name;
+			// default to just name, with first character in lowercase
+			ss << pre 
+			   << (char)std::tolower( static_cast<unsigned char>(name[0]) )
+			   << (name.c_str() + 1);
 		}
 
 		/// ensures type inst names are uppercase
 		static void ti_name( const std::string& name, std::stringstream& ss ) {
-			ss << (char)std::toupper( static_cast<unsigned char>(name[0]) )
-			   << (name.c_str() + 1);
+			unsigned i = 0;
+			while ( i < name.size() && name[i] == '_' ) { ++i; }
+			if ( i == name.size() ) {
+				ss << "Anon";
+				return;
+			}
+			ss << (char)std::toupper( static_cast<unsigned char>(name[i]) )
+			   << (name.c_str() + i + 1);
 		}
 
@@ -219,12 +227,15 @@
 			void previsit( BasicType* bt ) { ss << (int)bt->get_kind(); }
 
-			// pointers represented as generic type
-			// TODO except pointer to function
-			void previsit( PointerType* ) { ss << "#$ptr<"; ++depth; }
-			void postvisit( PointerType* ) { --depth; ss << '>'; }
-
-			// arrays represented as generic type
+			// pointers (except function pointers) represented as generic type
+			void previsit( PointerType* pt ) {
+				if ( ! dynamic_cast<FunctionType*>(pt->base) ) { ss << "#$ptr<"; ++depth; }
+			}
+			void postvisit( PointerType* pt ) {
+				if ( ! dynamic_cast<FunctionType*>(pt->base) ) { --depth; ss << '>'; }
+			}
+
+			// arrays represented as generic pointers
 			void previsit( ArrayType* at ) {
-				ss << "#$arr<";
+				ss << "#$ptr<";
 				++depth;
 				at->base->accept( *visitor );
@@ -244,14 +255,13 @@
 			}
 
-			// encode function type as a 2-param generic type
-			// TODO handle forall functions
+			// print function types using prototype syntax
 			void previsit( FunctionType* ft ) {
-				ss << "#$fn<";
+				ss << '[';
 				++depth;
-				buildAsTuple( *visitor, from_decls( ft->returnVals ), ss );
-				ss << ' ';
-				buildAsTuple( *visitor, from_decls( ft->parameters ), ss );
+				build( *visitor, from_decls( ft->returnVals ), ss, preceded );
+				ss << " : ";
+				build( *visitor, from_decls( ft->parameters ), ss, terminated );
 				--depth;
-				ss << '>';
+				ss << ']';
 				visit_children = false;
 			}
@@ -341,8 +351,8 @@
 			}
 
-			// print variable declaration as zero-arg function
+			// print variable declaration in prototype syntax
 			PassVisitor<TypePrinter> printTy{ closed, ss };
 			norefs->accept( printTy );
-			ss << ' ';
+			ss << " &";
 			rp_name( name, ss );
 		}
@@ -381,8 +391,8 @@
 				: closed(closed), ss(ss) {}
 
-			/// Names handled as nullary function calls
+			/// Names handled as name expressions
 			void previsit( NameExpr* expr ) {
+				ss << '&';
 				rp_name( expr->name, ss );
-				ss << "()";
 			}
 
@@ -416,4 +426,9 @@
 			}
 
+			/// Already-resolved calls skipped
+			void previsit( ApplicationExpr* ) {
+				visit_children = false;
+			}
+
 			/// Address-of handled as operator
 			void previsit( AddressExpr* expr ) {
@@ -585,4 +600,12 @@
 
 		void previsit( FunctionDecl *decl ) {
+			// skip decls with ftype parameters
+			for ( TypeDecl* tyvar : decl->type->forall ) {
+				if ( tyvar->get_kind() == TypeDecl::Ftype ) {
+					visit_children = false;
+					return;
+				}
+			}
+
 			// add function as declaration
 			std::stringstream ss;
