For functions you can now use named arguments.
Argument names contribute to overload resolution.

//////////////////////////////////////////
#import <flx.flxh>
fun f(a:int, b:int)=> a + 2* b;
fun f(x:int, y:int)=> 2 * x + 5* y;

var d = f(b=1,a=2); // 4
println q"d=$(d)";

d = f(x=1,y=2); // 12
println q"d=$(d)";
////////////////////////////////////////

Uncaveats: (magic good stuff):

* unlike Python, because records are first class types,
  you can do with records what you do with tuples:
  
  var x = (a=2,b=1);
  var d = f x;

  That is, you don't have to specify the 'argument names'
  in the actual application.

Oh well:

  You can't mix positional and named arguments. 
  I doubt this would make a lot of sense with overloading.

  There are no default arguments. This DOES mix with 
  overloading (see C++). It is more or less mandatory
  for functions with many arguments, since spelling
  out all the overloads for N defaults yields 2^N functions.

Caveats:

* THIS DOES NOT WORK FOR PROCEDURE CALLS YET.
* THE ARGUMENT RECORD MUST HAVE AT LEAST TWO COMPONENTS.
* IN CURRIED FUNCTIONS, ONLY WORKS ON THE FIRST ARGUMENT

To consider:

It would be interesting to consider automatic coercions:

fun f(a:int, b:int)=> a + 2* b;
f (a=1,b=2,c=3); 

This currently fails: there must be an exact match.
However, allowing subtyping is trivial to implement, and in fact
is simpler than the current algorithm which checks the record
and function have the same number of arguments.

More complex would be an overload specialisation rule based
on record subtyping. That is, if there is an ambiguous call
with a record matching several functions, one is selected
the same way specialisations are: the function with the maximal
number of components is selected if one exists, otherwise
if there is more than one it is ambiguous.

Now, why would you want to do this? Because it allows you
to write record polymorphic functions. This is 'ad hoc'
polymorphism, not parametric polymorphism, but still useful
in the same way as overloading: more or less it is overloading
on the data type instead of the function.

For example:

        var erick = (
                name="Erick", 
                job="programmer"
        );
        var john= (
                name = "John",
                occupation="bludger"
        );

        fun get_name (name:string)=>name;
        // WOOPS .. won't work due to 'two arguments' caveat .. :)

        println$ get_name erick;
        println$ get_name john;

The arguments don't even have the same type. And now,
if I extend the data:

        var erick = (
                name="Erick", 
                job="programmer",
                role="manager"
        );

it still all works. Note you can do this NOW with an explicit coercion:

        typedef named = struct { name: string; };
        println$ get_name (erick:named);
        println$ get_name (john:named);


Note that record pattern matching is *already* generic.

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to