I’ve been playing around with D, trying to mimic Scala style curryable functions by chaining lambda expressions.
I came up with this:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
class C static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
This is what I get when I run it:
global 3
struct 1528543170
Segmentation fault
As you can see, my method works well for the global function variable, but the struct’s static function variable gives junk result, and the class’s static function variable fails completely.
If I remove the x from the return expression – function(immutable int x)=>(immutable int y)=>(y) – the struct version gives the correct result(2), but the class version still fails.
If I use a regular method, instead of a function variable:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
class C
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
it works just fine:
global 3
struct 3
class 3
And I also get the advantage of using delegates(the compiler won’t allow delegates in the first version) – but this style is less elegant.
I am well aware that D has the curry function in the std.functional library for currying functions, but sometimes it’s more comfortable to make a function curryable by default, and beside – I’m curious to know why my first version doesn’t work.
Any ideas?
UPDATE
OK, I’ve filed a bug. I’ve done some more digging, and it turns out the argument list of foo gets shifted, and that’s why x gets junk data.
Honestly, it looks like you ran into a compiler bug. Please report it. Since the variables in the struct and class are static, their behavior should be identical to that of the module-level variable, and clearly, it’s not.