2012-06-11 11 views
6

Grałem z D, próbując naśladować Scala style curryable functions przez łańcuchy wyrażeń lambda.Tworzenie funkcji curry za pomocą lambdas w D nie działa jako klasa struct memebers

wymyśliłem to:

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)); 
} 

To co mam, kiedy go uruchomić:

global 3 
struct 1528543170 
Segmentation fault 

Jak widać, moja metoda działa dobrze dla globalnej zmiennej funkcji, ale zmienna statyczna funkcji struct daje wynik śmieciowy, a zmienna funkcji statycznej klasy zawodzi całkowicie. Po usunięciu x z wyrażenia zwrotnego - function(immutable int x)=>(immutable int y)=>(y) - wersja struct daje poprawny wynik (2), ale wersja klasy nadal kończy się niepowodzeniem.

Jeśli używam regularny sposób, zamiast zmiennej Funkcja:

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)); 
} 

to działa dobrze:

global 3 
struct 3 
class 3 

I również uzyskać Zaletą korzystania z delegatów (kompilator wygrał” t pozwalają delegatom w pierwszej wersji) - ale ten styl jest mniej elegancki.

Doskonale zdaję sobie sprawę, że D ma funkcję curry w bibliotece std.functional dla funkcji curry, ale czasami wygodniej jest ustawić funkcję, którą można programować domyślnie, a obok - zastanawiam się, dlaczego moja pierwsza wersja nie działa. t działa.

Wszelkie pomysły?

UPDATE

OK, I've filed a bug. Zrobiłem więcej kopania i okazuje się, że lista argumentów foo zostaje przesunięta, dlatego x dostaje niepotrzebne dane.

+0

WHOA Można powiedzieć "function' * i * say' => 'w tym samym czasie ?! Nie wiedziałem tego! :) – Mehrdad

+0

Przy okazji, czy przypadkiem nie wypowiadałeś 'static __gshared' zamiast' static'? * Może * to zadziała (palce skrzyżowane ... nie mam przy sobie kompilatora) – Mehrdad

Odpowiedz

4

Szczerze mówiąc, wygląda na to, że napotkano błąd kompilatora. Please report it. Ponieważ zmienne w strukturze i klasie są statyczne, ich zachowanie powinno być identyczne jak w przypadku zmiennej na poziomie modułu, a jasne, że nie.

+0

To naprawdę jest błąd kompilatora. Zawęziłem go i zgłosiłem. –