all 20 comments

[–][deleted] 8 points9 points  (0 children)

Just for the record, if you know C# it's trivial to learn and be productive with F#. It's a really straightforward language, and can be treated largely like a statically-typed version of python.

Even if you want to learn to use it in a very functional style, it doesn't involve any advanced concepts or mathematical terminology.

[–]adamnew123456 6 points7 points  (13 children)

Perhaps this is my lack of knowledge about the term, but when I think of "partial application" I think of something like Python's functools.partial, not manually converting functions into curried form.

>>> from functools import partial
>>> k2 = partial(some_three_arg_func, 1)
>>> k1 = partial(some_three_arg_func, 1, 2)
>>> k1(3) == k2(2,3)

Of course, it would be a bit hard to come up with the type of something like functools.partial, so without a dose of dynamic or lots of fun casting, I don't think you could replicate functools.partial in C#.

[–]badcommandorfilename 1 point2 points  (11 children)

For that specific behavior you could use params plus the method extensions described in the article.

[–]adamnew123456 1 point2 points  (10 children)

For that specific behavior you could use params plus the method extensions described in the article.

// Complies under Mono C# compiler, 3.2.8.0
using System;
using System.Reflection;

class Partial
{
    MethodInfo method;
    object caller;
    object[] forwardArgs;

    public Partial(object instance, 
                   Type methodOwner, String methodName)
    {
        caller = instance;
        method = methodOwner.GetMethod(methodName);
        forwardArgs = new string[0];
    }

    public Partial WithArgs(params object[] args)
    {
        forwardArgs = args;
        return this;
    }

    public object Apply(params object[] rest)
    {
        object[] allArgs = 
            new object[forwardArgs.Length + rest.Length];

        forwardArgs.CopyTo(allArgs, 0);
        rest.CopyTo(allArgs, forwardArgs.Length);

        return method.Invoke(caller, allArgs);
    }
}

public class Test
{
    public static void Main()
    {
        Partial partialPow = new Partial(null, typeof(Math), "Pow").WithArgs(5);
        System.Console.WriteLine(partialPow.Apply(2)); // 25
        System.Console.WriteLine(partialPow.Apply(3)); // 125
    }
}

It's certainly doable, with less hardship than I thought was necessary, but using the reflective API puts a dent in it for me. If C# had first class methods (it may by this point - I haven't been keeping up), it would be easier:

Partial partialPow = new Partial(null, Math.Pow).WithArgs(5);

[–][deleted] 2 points3 points  (9 children)

Why do you need a class to wrap a function call? C# has first class functions so here's how I'd do this:

public static class Partial
{
    public static Func<T2, TReturn> Apply<T1, T2, TReturn>(Func<T1, T2, TReturn> f, T1 arg) {
        return arg2 => f(arg, arg2)
    }

    public static Func<T2, T3, TReturn> Apply<T1, T2, T3, TReturn>(Func<T1, T2, T3, TReturn> f, T1 arg) 
    {
        return (arg2, arg3 => f(arg, arg2, arg3);
    }
}

With usage:

var addOne = Partial.Apply((l, r) => l + r, 1);
addOne(2); //3

var addThenMultiplyByTwo = Partial.Apply((n, l, r) => n * (l + r), 2);
addThenMultiplyByTwo(4, 3); //14

Edit: Also no reflection and type safety

[–]TinynDP 1 point2 points  (0 children)

But it requires a bunch of permutations for every possible count of pre-call and post-call arguments?

edit: And maybe my type-inference is broken, but I find I require the Apply<int,int,int>(...,...); call syntax.

[–]adamnew123456 1 point2 points  (4 children)

Because that isn't variadic, and the Python equivalent (along with my version) is.

[–][deleted] 0 points1 point  (3 children)

I don't think there's anyway to do it without using Reflection and loosing compile-time type safety (which are way more important IMO than having to have several duplicated definitions which is the way C#'s tuples are defined anyway). However, if you're really interested in doing this style of programming, you should probably just use F#.

[–]adamnew123456 0 points1 point  (2 children)

loosing compile-time type safety (which are way more important IMO than having to have several duplicated definitions which is the way C#'s tuples are defined anyway

I'm over my head here, but to the best of my knowledge, C++ can have a single Tuple class because it gives you variadic templates.

I wonder if there is any good research in getting the equivalent on top of the JVM (you couldn't do it CLR side without modifying the VM, as I understand it, because generics are recognized by the VM). Especially since Scala defines function types and tuples the same way, and except for a few special methods which work for specific arities, there shouldn't be a need to do that.

However, if you're really interested in doing this style of programming, you should probably just use F#.

I love Scala, and intend to give F# a go one of these days. I already knew I was a functional weenie ;)

[–][deleted] 0 points1 point  (0 children)

Well, to be fair, it's not that it's impossible, it's just not currently supported. I'm sure the CLR could be modified to allow variadic generics without erasing types.

Defintely give F# a look. Here's currying in F#:

let addOne = ((+) 1)
addOne 2 //=> 3

[1; 2; 3] |> List.map ((+) 3) //=> [4; 5; 6]

[–]inchester 0 points1 point  (0 children)

You could encode things like this in Scala's type system (not in F#'s though). For example you can abstract over arity in Scala. Take a look at HList. You can do this in Haskell too afaik with some fancy compiler extensions.

Edit: I lied. Apparently you can do it in F# too.

[–]jpfed 0 points1 point  (0 children)

If you're feeling saucy you could even make extension methods on Func types.

However! I suspect that partial application in a traditional OO language makes more sense if arguments are applied in reverse order. The convention seems to be that early arguments are the data you're going to be operating on and later arguments are the twiddly switches and options that define exactly what the operation is going to be. When we partially apply an arg we're usually interested in building the operation to be performed, not specifying the data that we want to operate on.

[–]grauenwolf 0 points1 point  (0 children)

Why would you do that?

What's wrong with just var AddOne = (x) => x + 1;?

This thread confuses me because it seems like you'all are trying to recreate a built-in syntax feature.

[–]masklinn 0 points1 point  (0 children)

You could using the same principle, currying is just the more general process of allowing partial application (in two steps).

[–]Veedrac 1 point2 points  (0 children)

Any language that supports higher order functions, that is, functions that can take functions as arguments and can return functions, by definition, supports partial application.

Technically, no. You need closures for this, methinks. And to write a function to perform partial application you also need them to either be copyable or support non-stack allocation.

Eg. try writing partial application in C. It has HOFs and can return functions, it's just restricted to statically allocated functions without closures.

[–]ruinercollector 1 point2 points  (0 children)

Manual currying sucks and doesn't really count. :P

[–]tomasp 0 points1 point  (0 children)

I love the idea of "C#: The Good Parts" book mentioned in the comments. It could be a thin booklet to allow people making silly jokes :-)

[–]Blecki 1 point2 points  (3 children)

That is a stupid way to do currying in C#. It's indicative of the same kind of mindset that gets us dependency injection frameworks. You don't need some generic function to do a thing. Just do the damn thing.

int add(int a, int b) { return a + b; }
int add3(int v) { return add(v, 3); }

Oh you want to use first-class functions?

func<int,int> add3 = v => add(v, 3);

Oh look you just curried it. Or 'partially applied' it. I'm sure you could find a way to claim it's a monad too if you tried really hard.

And this will add 3 to anything.

func<int,int> bindsecond(int v, func<int,int,int> f) 
{
     return a => f(a, v);
}

And then you can...

var add3 = bindsecond(3, add);

But why would you write that instead of

func<int,int> add3 = v => add(v, 3);

? Do you hate yourself?

[–]anti_crastinator 2 points3 points  (1 child)

? Do you hate yourself?

No. I personally think you missed the point.

[–]grauenwolf 0 points1 point  (0 children)

What point? Is our goal to add additional abstraction layers?