On Fri, 2007-01-12 at 13:28 -0800, Erick Tryzelaar wrote: > skaller wrote: []
Ok, this now works for functions and procedures ONLY at the moment: ////////////////////////////////////////////////////// #import <flx.flxh> print "b4 fred"; endl; namespace fred { print "fred1 start"; endl; var x = 1; proc f() { print "f"; endl; } print "fred1 end"; endl; } print "between freds <not!>"; endl; namespace fred { print "fred2 start"; endl; var y = 1; proc g() { print "g"; endl; } print "fred2 end"; endl; }; proc fred::h() { print "h"; endl; } // ^^^^^^^ <-- ***************************** print "after freds"; endl; open fred; print x; print " "; print y; endl; f(); g(); h(); //////////////////////////////////// The way it works is simple: it is mapped to namespace fred { proc h() { .. } } in the parser. This needs to be done for all the other declarations: typedefs, variables, etc, but hasn't been yet. A conflict in my mind: since module M[t] { fun f .. //1 actually means module M { fun f[t] ... //2 why not make it so namespaces just do that? The point being, each defintion *separately*, so you could write: namespace M { .. namespace M[t] { .. namespace M[u,v] { ... namespace M[k] { ... After all, it just puts the type variables into the things defined in the {'s. The PROBLEM is that actually (1) and (2) are NOT equivalent: module M[t] { typedef t = int; proc f: t = ""; .. means proc f[t]: int = ""; and not proc f[t]: t = ""; and similar issues where the module type argument contains a constraint like t = v and v is a typedef both inside and outside the scope of the module, the v should bind to the outer v if the constraint is written in the module clause, but the inner v if written in the function clause. It's possible this doesn't even work correctly now, however the scope is determined at binding time which is probably right (even if the wrong scope is chosen :) To make the 'separate' namespace definitions work like that would require a different technique to the one I've implemented, which is basically cut and paste of text actually it cuts and pastes syntax trees after macro processing recursively prior to desugaring .. but the effect is much the same: its currently a simple rewriting rule with no deep consequences or power. > Could we do: > > namespace foo::bar[t]::baz[u where u = t + 1] { ... > At present my change above doesn't include namespaces, only functions and procedures, but I can't see a reason not to finish the job: the above would just translate to namespace foo { namespace bar[t] { namespace baz[u where u = t + 1] { ... > For the initial implementation of namespaces, I'd be fine with them not > being generic. But if it's easy to do, then no reason to remove the > functionality. It's the other way around really: its hard to avoid them including the type variable lists. If they're not parsed the standard way which uses grammar production 'tvarlist' they don't conform with the pattern used everywhere else. > I'd vote that you'd have to fully specify the type > variables and constraints, if you want to use them, as thats the > simplest solution. So: > > namespace foo::bar[t]::baz[u where u = t + 1] { var x = 1; } > namespace foo::bar[t]::baz[u where u = t + 1] { var y = 1; } > > I think the self-documenting features of this are pretty handy. Of > course, having to propagate changes could get obnoxious. I see two alternatives: (1) Only *allow* the type variables in the first 'namespace' clause. After that they're inherited. (2) Make it so they're independent for each clause .. see above for the problem with that .. I'd have to use a more invasive implementation. It can be done though. There is one downside: in the future the vs of a module (the type variable list is called 'vs') may mean even more than just every entry in the module has the (bound) vs list prepended to its private vs list, which is the current meaning. In particular note that for typeclasses the vs list does NOT work like that. The typeclass itself is a proper object with a vs list .. the purpose being that you can't instantiate each function of a typeclass with different assignments to the typeclass vs: within a typeclass the functions are monomorphic. > Do you think > something like this would be that popular vs just using modules? If not, > it might not be worth putting the effort into coming up with a solution. how can one judge popularity when there are currently no users? > Lastly, does this suggest that namespaces are really just open modules? At the moment, yes. > I can't remember, do we have functors yet? If not and we add them, could > (and should) we be able to pass a namespace to one? We have typeclasses, which are 'sort of' like functors. ML style module functors need interfaces. The closedness of modules is important in this setting. However I can't see why 'open' modules couldn't be arguments to functors provided they were complete enough to satisfy the interface. For the functor itself it gets more complex .. especially if the interface (domain of the functor) is extensible too: that's basically a weak kind of 'inheritance' which allows 'adding' methods. To ensure good typing a proper extension model should be used. 'Adding overloads' is already a weak way to specify a 'generic' function (it's weak because they can be scattered all over the place in different scopes, which allows 'hijacking'). A *strong* form of overloading would prevent this .. and we have it: typeclasses. Typeclasses actually provide 'ad hoc' polymorphism, but they do it with a 'parametric' polymorphic interface: the typeclasses are parametric and the instances are the 'ad hoc' things. This provides much of the power of C++ templates with specialisations WITHOUT compromising safety by allowing hijacking, particularly without the mess created by dependent name lookup in C++. So .. we'd be looking for some similar stronger system to ensure functors didn't get broken. The problems here are different in a language with separate compilation, which Felix doesn't have (yet). However Felix is deliberately 'phased' in such a way that separate compilation might be possible: that's why the problem with generics exists: instantiation is done late, emulating what a language with separate compilation would have to do at link time. BTW: functors are actually easy to implement. It's just a module with some typedefs: functor F[t,u] { .... } module K = F[int,long]; is just module K { typedef t = int; u = long; ... } (more or less!) In the 'old' days of functors this was a pain, because the AST included cached bindings of types, so the ... would have had to be copied physically. But that's gone now, so the above implementation of functors would really work. The PROBLEM with functors was that the statement: module K = F[int, long]; open K; which you'll note is exactly like writing open F[int,long]; is basically just a 'specialisation' of the functor, and the technology to implement that didn't exist before. It does now! The real issue here is that you can open K, and potentially use K to define F. In fact .. apart from the scope of binding 'int,long', we already HAVE functors: ordinary modules right now are functors over their type parameters. You just can't pass in non-type things like values and functions, and you can't name a specialisation .. even though you can open one! Note that the word 'functor' is ambiguous. Every polymorphic type is a type functor already. A type functor is just a (structure preserving) mapping from types to types. Ditto module functors .. just mappings from modules to modules. Typeclasses are functors from types to modules (in effect a typeclass instance is a module with only functions in it). Ultimately .. ALL of this can be subsumed by a single kind of entity: the class. Surprisingly C++ is already quite close to a unified high level system. -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language