On 17/01/2013, at 5:32 AM, Dobes Vandermeer wrote: > > Well, if people are shadowing existing function definitions with new > variables containing a closure, that is confusing. How does felix currently > handle something like: > > fun f(x:int) => x*x > fun g(a) { > fun f(b:string) = a+b; > return f(5); > } > > Do the "inner" and "outer" f somehow merge together so that it selects > between both inner AND outer versions of f?
The name of a function, for hiding purposes, is a pair consisting of the function identifier and the function signature. Therefore both of the f's above are visible: the names are the same, but the argument types are not. However for a variable there's no signature, there's no overloading: the type is checked, but there's no overload resolution. So a variable will hide all functions. In the Ocaml code, the lookup environment is a stack. Each level of the stack consists of a primary dictionary, and a list of secondary dictionaries. The latter contain views of other scopes constructed by "open" directives. The primary dictionary is a hash table and is searched first, then the secondaries, and then the stack is popped and we repeat. Each dictionary entry is marked as "NonFunction" or "Function". If it's marked "Function" it is a set pairs: signature, table index Overloading proceeds on the signatures. If there are no matches, we continue with the next dictionary. If there's an ambiguity abort. If there are multiple matches due to polymorphism we rank them based on subtyping rules, i.e. a more specialised type beats a less specialised one provided the more specialised one is a strict "subset" of the more specialised one. If there is a set of matches remaining, then any constraints are applied (typeset membership). Finally we end up with one match (return it), more than one match (ambiguity) or no matches (pop the stack and retry) One downside of this algorithm is that if you get no matches the diagnostic says "no matches". If you get an ambiguity, on the other hand, it lists all the candidates. You cannot do that for no matches because you only get no matches when you hit the bottom of the stack which has no symbols at all. the algorithm is similar to C++ except: (a) functions are hidden by signature not name. C++ does it wrong, everyone agrees, but it is too late to change it. (b) C++ "using" directives do not implement the "shadow" directories that Felix does for opens. Felix allows you to hide any opened symbol with a new declaration but don't forget, symbol for functions includes the signature. (c) Felix opens can do specialisations! C++ cannot do that because namespaces cannot be polymorphic. For example if you have class List[T] { fun cons ... you can do: open[U] List[U*U]; which makes functions on lists of pairs of the same type visible but not other list functions. You can even do this: open [U:ints] List[U*U]; which makes lists of pairs on integer types visible but not others. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Master Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery and much more. Keep your Java skills current with LearnJavaNow - 200+ hours of step-by-step video tutorials by Java experts. SALE $49.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122612 _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language