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

Reply via email to