www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5829] New: An improvement or alternative to std.functional.curry

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5829

           Summary: An improvement or alternative to std.functional.curry
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: andrej.mitrovich gmail.com



12:05:16 PDT ---
Currently, std.functional.curry only accepts binding one argument against a
function. Is there a reason why curry shouldn't be allowed to accept multiple
arguments? Because this is easily possible to do.

Maybe another name for this method would be "partial function application". In
any case, I have a very basic implementation that works with multiple arguments
and even variadic functions. An implementation and a small test case follow:

import std.stdio;
import std.traits;
import std.metastrings;
import std.functional;

template count(T...)
{
    enum count = T.length;
}

template myCurry(alias fun, args...)
{
    static if (__traits(compiles, (ParameterTypeTuple!fun).length))
    {
        static if (args.length > (ParameterTypeTuple!fun).length)
        {
            static assert(0, Format!("Tried to pass too many arguments - %s,
max is %s.",
                                     count!args,
(ParameterTypeTuple!fun).length));
        }
    }

    auto myCurry(T...)(T t)
    {
        return fun(args, t);
    }    
}

void foo(int x, int y, int z)
{
    writefln("%s %s %s", x, y, z);
}

void bar(int[] values...)
{
    foreach (val; values)
    {
        writef("%s ", val);
    }
    writeln();
}

alias myCurry!(foo,    1)     oneFoo;
alias myCurry!(oneFoo, 2)     twoFoo;
alias myCurry!(twoFoo, 3)     threeFoo;
alias myCurry!(foo, 1, 2, 3)  threeFooAgain;
alias myCurry!(foo)           fooNoCurry;

alias myCurry!(bar,    1)   oneBar;
alias myCurry!(oneBar, 2)   twoBar;
alias myCurry!(twoBar, 3)   threeBar;
alias myCurry!(bar)         barNoCurry;

void main()
{
    oneFoo(2, 3);
    twoFoo(3);
    threeFoo();
    threeFooAgain();
    fooNoCurry(1, 2, 3);

    oneBar(2, 3, 4, 5);
    twoBar(3, 4, 5);
    threeBar(4, 5);
    barNoCurry(1, 2, 3, 4, 5);
}

Note that std.functional.curry doesn't work with variadic function parameters,
but the myCurry implementation does.

Three notes:
1. The count template is used because there seems to be a bug if I try to
reference args.length inside a static if body. It's odd since I can reference
args.length inside the static if expression itself, but not its body. Maybe I
should file this as a bug.

2. The first static if is used to allow currying one function against another
already curried function. If I don't check whether a call to
`ParameterTypeTuple` compiles, it will fail with a weird error such as "Tuple
length 1 exceeds length 1". This is possibly another bug.

3. I haven't tested this in thoroughly, so this is a really basic
implementation and it might have bugs. 

In any case I think it would be worthwhile to have a curry-like function that
works with multiple arguments, even if this implementation is too simple. In
that case someone could implement it in a better way.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 10 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5829


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 10 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5829


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WONTFIX



14:17:06 PDT ---
I'm silly, this is a form of partial-function application, not curry. Anyway
it's too crude to be included so I'm closing it down until I figure out
something nicer.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 26 2011