Kan någon förklara exakt vad Currying (i context av functional programming) är och varför det är bra. En del har för mycket fritid! OOP funkar, använd det :-D Jag kanske fattar lite iaf. Man kanske skulle kunna beskriva det så här: Ok jag tror jag är med på det hela. <b>>Så ok, jag är med på vad man gör och hur det fungerar, men när var och hur är det användbart då?</b> <b>En del har för mycket fritid! OOP funkar, använd det :-D</b> Fast nu är jag lite osäker. for_each(mult(2), arr); Jag tror nog att man kan göra samma sak i alla andra språk som har lambda-funktioner också. //orginal<b>Man kanske skulle kunna beskriva det så här: <b>>Det där är partiell applikation, inte currering</b> En currerad funktion är en funktion som tar ett argument och returnerar en funktion. När man ger funktionen ett argument får man alltså tillbaka en funktion. Man har då gjort en partiell applikation (applicering?). Man kan sedan göra ytterligare en partiell applikation, dvs ge ett till argument, vilket då blir argument till den funktion som returnerades. Om man nu får tillbaka ett objekt som inte är en funktion, har en fullständig applikation gjorts. OK, jag förstår vad tanken är bakom. <b>Vissa är intresserade av att lära nytt, andra av att trampa i gamla spår.</b> Well stödet för FP i C# är ju iaf nytt. <b>>Nytt å nytt... LISP e väl från 50-talet typ..</b> Jag vet inte hur användbart det är att använda currying i C#, känns som om currying gör mest nytta i språk som t.ex. ML och Haskell där det faller sig mer naturligt att använda. Men jag kan ha fel, är inte expert på varken FP eller C# 3.0 :-) >En del har för mycket fritid! OOP funkar, använd det :-D LINQ föreslår att det inte behöver vara (FP XOR OOP)? :) För det första är det ett annat sätt att arbeta på och tänka, vilket gör att det är svårt att se nyttan av grejerna i ett imperativt område (EDIT: vad jag menar är att det kan vara bra att tvingas till FP först och sen använda FP när man väl förstått det i imperativa språk). Nytt sätt att arbeta på.. är väl ändå att ta i? Ok det här börjar bli lite offtopic. "Nytt sätt att arbeta" - ja man arbetar ofta bottom-up i FP, och generaliserar ofta automatiskt. Det innebär att man inte har riktigt samma struktur i hur man bygger upp ett program. Lite halv cowboy-coding gör inte så mycket, det löser man lätt efterhand - planering tappar lite av sin vikt. Om man som .Net-geek vill börja lära sig riktig FP kanske det är en bra idé att starta med F#. Baserat på OCaml och från grunden utvecklat som ett .Net-språk. Då har man ju i alla fall VS och sitt kära ramverk att hålla i handen... :-) För att återkomma lite till ämnet. Nu har jag inte riktigt förstått mig på C#-syntaxen, men det här låter ju precis som det jag och Per diskuterade ovan. I så fall är det inte "äkta currying" utan bara partiell tillämpning. Och det är det jag har så svårt att se skillnaden på. <b>Nu har jag inte riktigt förstått mig på C#-syntaxen</b> Aha, nu hajar jag, men det är väl i så fall just för att man inte kan ange färre antal parametrar, i Haskell är det ju i princip ingen nytta att ha en "avcurryfierad" funktion? Nu förstod inte jag vad du menade... Vad jag menade var att <b>>Kollade förresten på språket Cat som en av dina länkar ovan handlade om. Intressant med ett stackbaserat, funktionellt och typat språk.</b> <b>Int -> Int -> Int</b> är ju egentligen bara syntaktiskt socker för <b>Int -> (Int -> Int)</b>, dvs man gör <b>-></b> högerassociativ. Jo, precis, det var det jag menade. Men det finns liksom ingen direkt anledning att använda Jag gillar verkligen den här webbplatsen, för det är på den här webbplatsen som jag kan spela online-spelautomater enkelt och enkelt - https://pirots3.com/sv/ . Jag gillar den här webbplatsen eftersom det finns många riktigt coola och högkvalitativa spelautomater som du kan spela säkert och fritt!!Currying - functional programming
C# 3 har ju fått en del stöd för functional programming och jag försöker kränga min stackars OO-hjärna runt FP men det tar emot lite :-)
Har kollat på den här sidan men det hjälpte inte alls.
http://en.wikipedia.org/wiki/Currying
Det pratas om att reducera inparams och att göra funktiner som returnerar funktioner.
Säg att vi har:
Func<int,int,int> mul = (x, y) => x * y;
Om man curryfierar den då? vad händer då?
Är det här en curryfiering av mul?
Func<int,int> pow2 = (x) => mul (x,x);
Får hjärnblödning på det här snart :-PSv: Currying - functional programming
Sv: Currying - functional programming
Är det här rätt?
//orginal
Func<int, int, int> mul = (x, y) => x * y;
//curryfierad
Func<int, Func<int, int>> curryMul = x => (y => x * y);
int res = curryMul (2)(3);Sv:Currying - functional programming
1. Du har en funktion med n argument.
2. Genom currying så skapar du en ny funktion som tar m (m<n) argument, genom att n-m argument redan är angivna.
Det ser ut som att det du gör är rätt iom de två parenteserna på slutet. Tyvärr kan jag inte C# så jag vet inte om det stämmer.
Principen ska i så fall vara att curryMul(2) i sig är en funktion. Om vi kallar den f så tar f ett argument och returnernar 2*det argumentet.Sv: Currying - functional programming
en liten rättning av min egen kod:
//curryfierad
Func<int, Func<int, int>> curryMul = x => y => mul( x , y) ;
Så jag får en funktion som tar en param och ger mig ytterligare en funktion som även den tar en param.
och när den sedan anropas så anropas den riktiga orginalfunktionen med de params som skickats genom curry funktionerna.
Så ok, jag är med på vad man gör och hur det fungerar, men när var och hur är det användbart då?
Alla exempel på internet är ju skrivna för ruby eller andra oläsliga språk ;-)Sv:Currying - functional programming
Jag har länge kört så här:
lbl1:
instruktioner
if villkor == true goto lbl1
lbl2:
Och har läst att "while"-loopen skulle vara bättre. Men när, var och hur är det användbart?
Poängen är att det är en sorts abstraktion, det är svårt att säga att "här är det bättre", utan det förenklar och gör koden renare när man väl ser det. Precis som klasser var första gången man såg det - "men vad är poängen?". Det är det som gör det så svårt att sälja in fp till folk.
Låt säga att du vill skicka en funktion som argument till en annan funktion; vi skriver om for_each (pseudokod):
for_each(func f, array a)
{
for(i = a.begin(); i != a.end(); i++)
f(i);
}
Nu har vi funktionen mult(a, b), men vi vill bara dubbla värdena. Notera att "f" antas ta ett argument ovan, men att mult tar två. Det är ok eftersom vi bara behöver ett argument, vi vet det andra. Då gör vi:
for_each(mult(2), arr);
Istället för
double_the_val(val)
{
return mult(2, val);
}
for_each(double_the_val, arr);
Det blir enklare och renare.
(Kanske ska slänga in en disclaimer om att jag inte känner mig helt hundra på allt inom FP - ta inte det jag skriver som absolut sanning utan som min tolkning.)Sv:Currying - functional programming
Vissa är intresserade av att lära nytt, andra av att trampa i gamla spår.Sv: Currying - functional programming
http://lambda-the-ultimate.org/node/2266
http://www.haskell.org/haskellwiki/Currying
Jag hade för mig att det inte var fullt så enkelt. I princip betyder det väl samma sak, men Per kanske har en tydligare förklaring?Sv: Currying - functional programming
i C#3 skulle man kunna skriva
ForEach( i => mult(2,i).arr)
Eller med extension metoder
arr.ForEach( i => mult(2,i));
Där "i" är en inparam i en lambda som skickas in från foreach satsen.
Så i det fallet skulle jag inte behöva deklarera en ny metod (double_the_val(val))
utan kan använda lambdas direkt i ForEach
Så jag köper att det kan finnas nytta i andra språk där lambdas fungerar annorlunda osv.
Men just i C#3 så känns det som det mesta går att lösa utan currying och ändå få det väldigt rent o fint.
Så de som skriver om currying i .net, är det nördar som vill skryta om sin balla kod, eller är det bara jag som inte fattar varför det är så bra?Sv:Currying - functional programming
Om du läser länkarna där ovan ser du att i bl a Haskell pratar man knappt om currying eftersom det är implicit. Och där står det också att det inte är riktigt samma sak som att bara anropa med ett redan bestämt argument, det skiljer lite (även om jag inte ser exakt hur).
Poängen kanske är att det är en abstraktion som är så extremt vanlig att man har gett den ett eget namn. Sen finns det ju kopplingar till matematik, där den i högsta grad är relevant.
Per! Kan du någon bättre förklaring?Sv: Currying - functional programming
1. Du har en funktion med n argument.
2. Genom currying så skapar du en ny funktion som tar m (m<n) argument, genom att n-m argument redan är angivna.</b>
Det där är partiell applikation, inte currering (eller vad det heter på svenska). Men ibland kan det vara svårt att dra gränsen.
<b>//orginal
Func<int, int, int> mul = (x, y) => x * y;
//curryfierad
Func<int, Func<int, int>> curryMul = x => y => mul( x , y) ;</b>
Korrekt, du verkar ha börjat förstå det.
Varför currerar man funktioner? Främsta anledning som jag ser det just nu är att kunna skriva kortare och därmed ofta mer läsbart. Antag att du har en lista list och vill multiplicera varje element med 3. Med hjälp av funktionen mul ovan kan du skriva något i stil med list.Map(x => mul(3, x)), men med curryMul kan du skriva det kortare (bortsett från att namnet är längre): list.Map(curryMul(3)).Sv:Currying - functional programming
Mmm, det är ju det det står i länkarna ovan. Men hur beskriver man det?
Vad är skillnaden?Sv: Currying - functional programming
-- foo är en currerad funktion
foo :: a -> b -> c
-- partiell applikation av foo
foo (x :: a) :: b -> c
-- ytterligare partiell applikation, som ger en fullständig applikation av foo
foo (x :: a) (y :: b) :: cSv:Currying - functional programming
Men jag köper inte konceptet.
>>men med curryMul kan du skriva det kortare (bortsett från att namnet är längre): list.Map(curryMul(3)).
Jag anser att även om det blir aningen längre utan curry , så _ökar_ det läsbarheten..
arr.ForEach ( i => mul (2,i) )
är för mig mer läsbart än:
arr.ForEach (mul(2))
I det övre fallet ser jag klart och tydligt att det är en lambda som skickas in och jag ser även i vilket led "i" kommer skickas in.
Den nedre fungerar väl dessutom bara om det är den sista parametern i funktionen som ska ittereras?
tex : Foo (1,2,3,x) , eller Bar ("hej","du",x) .. men inte Mul(x,2)Sv: Currying - functional programming
Nytt å nytt... LISP e väl från 50-talet typ..
NYTT är SOA, LINQ, osv (inkl OOP och OOA så klart).Sv:Currying - functional programming
Hela linq bygger ju på FP (+lite syntax godis för standard frågor)
Här är en riktigt bra sida om FP o C#3
http://www.atrevido.net/blog/CommentView,guid,ed630fc6-cafa-450a-a6f2-7a570064f09a.aspx
Finns massor av nyttiga poster för att få c# koders att förstå hur man kan skriva mer FP'aktig kod.
tex:
Normal C#var tempAddresses = new List<MailAddress>();
foreach (string s in semicolonEmails.Split(';')) {
var ts = s.Trim();
if (ts == "") continue;
tempAddresses.Add(new MailAddress(ts));
}
var myAddresses = tempAddresses.ToArray();
vs.
FP stilvar myAddresses = semicolonEmails
.Split(';')
.Select(s => s.Trim())
.Where(s => s != "")
.Select(s => new MailAddress(s))
.ToArray();
Jag tycker den versionen som är i FP stil är så mycket renare och tydligare.
Sv: Currying - functional programming
Och LISP är, without doubt, det bästa språket. Förutom en liten mängd tråkiga lämningar från språkets barndom är det dessutom vansinnigt snyggt. Tyvärr är det bara om man förstår LISP man kommer till den insikten, och tyvärr är det sjukt svårt att förklara varför, förutom för andra som har hajat det...
Bara för att något är "nytt" betyder det inte att det är nytänkande.
<b>>NYTT är SOA, LINQ, osv (inkl OOP och OOA så klart).</b>
LINQ är ju (precis som Roger säger) ett försök att lägga in delar av FP i "moderna" språk. Faktum är att i stort sett alla tillägg som har kommit till imperativa språk sen början på 90-talet har funnits i LISP sen 70-80-talet.
Erlang startades 1987 enligt wikipedia. Jag har ingen jättekoll på vare sig SOA eller Erlang, men vad jag har förstått tvingar Erlang programmeraren till en viss grad av service-orientering, redan från början... Ericssons mjukvarusystem kan bytas ut i delar under drift, medan service:ar som är mitt i körning får köra klart, även om det så tar en dag. Kan du göra det med godtyckligt OOP-språk, out of the box?
Som sagt; nytt != nytänkande.Sv: Currying - functional programming
Jag har använt nåt som kanske skulle kunna klassas som currying i Javascript. Hade en uppslagstabell och en funktion, lookup(row, col), som om man skickade in två parametrar returnerade värdet i önskad cell. Skickade man bara in en parameter returnerdes en funktion som hade col fixerad till det inskickade värdet och som sedan kunde användas för uppslag mot just den kolumnen.
En artikel om currying i Javascript finns här: http://www.svendtofte.com/code/curried_javascript/Sv:Currying - functional programming
Frågan är om Google hade funnits om de använt OOP.
Mycket av deras framgång bygger på MapReduce (http://labs.google.com/papers/mapreduce.html).
MapReduce skrevs ioschförsig i C++ men det bygger på functional programming.
eller som någon utryckte det för ett par år sedan (hittar inte länken just nu):
"The very fact that Google invented MapReduce, and Microsoft didn't, says something about why Microsoft is still playing catch up trying to get basic search features to work, while Google has moved on to the next problem: building Skynet the world's largest massively parallel supercomputer. I don't think Microsoft completely understands just how far behind they are on that wave"Sv: Currying - functional programming
Sv:Currying - functional programming
För det andra så har ju LISP haft CLOS (OOP i LISP) sen runt 1986-1988, så det är ju inte direkt ett nytt förslag LINQ kommer med då... =)Sv: Currying - functional programming
Även med FP innebär det väl att vi behöver sitta framför en dataskärm och skriva kod.. ? :) Sv:Currying - functional programming
OOP vs FP.
Tråden var om currying och dess syfte.
Och jag tror vi kommit fram till att currying fyller sin funktion mest i de språk där det är lite mer naturligt.
där man faktiskt kan förkorta kod genom att använda det.
i C#3 så blir det _extra_ kod för att nyttja currying och därmed försvinner själva poängen..
Eller? ;-)Sv: Currying - functional programming
<b>>OOP vs FP.</b>
Skulle snarare säga
icke FP vs. FP
Tror inte det är någon här som har sagt att OOP är kass, mer Ola som har sagt att FP är onödigt.
Men gör det så mycket att det kommer off topic?
Själva ämnet är ju avhandlat, och lite diskussion kring det är väl bara nyttigt?
<b>>Och jag tror vi kommit fram till att currying fyller sin funktion mest i de språk där det är lite mer naturligt.</b>
Mmm, men man kan ju också säga typ att "ett språk är inte FP om man inte har currying", att det finns en slags matematisk bakgrund till det, och då blir det ju nödvändigt att tillåta det.
Lite som att man inte får en viss grad av OOP utan virtuella funktioner. "Lite oop" får du utan, men inte fullt.Sv:Currying - functional programming
F#: http://research.microsoft.com/fsharp/about.aspxSv: Currying - functional programming
om jag skulle göra
Func<int,int> mul2 = x => mul(2,x);
skulle även det klassas som currying?
enligt def från wikipedia så ska man ta en fler param funktion och omvandla till en enparam funktion.
det blir ju rent praktiskt samma som:
Func<int,Func<int,int>> curryMul = x => y => mul(x,y);
Func<int,int> mul2 = curryMul(2);
Så, klassas det fortfarande som currying om man manuellt wrappar upp slutfunktionen och förser funktionen med egna konstanter ?Sv:Currying - functional programming
Sv: Currying - functional programming
Func<int, int, int> mul = (x, y) => x*y;
Func<int,Func<int,int>> curryMul = x => y => mul(x,y);
motsvarar
mul :: (Int , Int)-> Int
mul = \(x, y) -> x*y
curryMul :: Int -> (Int -> Int)
curryMul = \x => \y => mul (x, y)
Men visst, jag är inte riktigt med på varför man skriver <b>Func<int, int, int></b> och inte t.ex. <b>Func<Pair<int, int>, int></b>.
Sv:Currying - functional programming
Sv: Currying - functional programming
Kollade förresten på språket Cat som en av dina länkar ovan handlade om. Intressant med ett stackbaserat, funktionellt och typat språk.Sv:Currying - functional programming
curryMul :: Int -> (Int -> Int)
Inte skiljer sig från
curryMul :: Int -> Int -> Int
Och därmed så är det lite luddigare vad currying faktiskt är i Haskell.Sv:Currying - functional programming
Mmm, det känns som att det är till stor del baserat på hur LISP är tänkt. Genom att vara stackbaserat och använda RPN så är det vansinnigt enkelt att göra parsers för det. Min gissning är att det startade som ett rent hobbyprojekt för att det blev så pass enkelt att hantera.Sv: Currying - functional programming
Sv:Currying - functional programming
(Int, Int) -> Int
Istället för att använda
Int -> Int -> Int
Såvida inte paret i sig betyder något. Hence, oftast nte speciellt meningsfullt att prata om currying i Haskell - standardsättet att definiera funktioner är "curryade" (nu måste det komma ett bättre ord...).Sv: Currying - functional programming