Entwickler-Ecke

Andere .NET-Sprachen - "Haskell"-Quicksort in Chrome


Christian S. - Fr 25.01.08 21:15
Titel: "Haskell"-Quicksort in Chrome
Hallo!

Zuerst eine Bemerkung: Ich versuche nicht, eine besonders sinnvolle oder performante Implementation des Quicksort zu finden, sondern möchte etwas ähnliches wie bei dem Haskell-Beispiel [http://de.wikipedia.org/wiki/Haskell_%28Programmiersprache%29#QuickSort] haben.

Nun zum Problem. Als normale Methode klappt das:

Delphi-Prism-Quelltext
1:
2:
3:
4:
5:
class method ConsoleApp.Sort(xs : List<Integer>) : List<Integer>;
begin
  if xs.Count = 0 then exit new List<Integer>;    
  result := Sort(xs.Where(y -> y < xs[0]).ToList).Concat([xs[0]]).Concat(Sort(xs.Where(y -> y > xs[0]).ToList)).ToList;
end;


Möchte ich das auch noch als Lambda-Ausdruck machen, geht's nicht mehr:

Delphi-Prism-Quelltext
1:
2:
  var sort : Func<List<Int32>, List<Int32>> := 
    xs -> iif(xs.Count = 0new List<Int32>, sort(xs.Where(y -> y < xs[0]).ToList).Concat([xs[0]]).Concat(sort(xs.Where(y -> y > xs[0]).ToList)).ToList);


Da erhalte ich dann eine NRE, die ich mir nicht erklären kann. :nixweiss: Die bezieht sich dann auf das y < xs[0].

Wo mache ich da den Fehler?

Grüße
Christian


Kha - Sa 26.01.08 01:05

Uff... bin gerade vom Chrome-Compiler ein _wenig_ verwirrt :gruebel: . Entweder bin ich komplett auf dem falschen Dampfer oder Chrome unterstützt entweder überhaupt keine Closures oder in einer Art, die ich (und damit indirekt du ;) ) noch nicht verstanden habe :? :? .
Solange jedenfalls folgender Schnippsel nicht funktioniert, wird deine rekursive Lambda-Funktion ebenfalls nicht funktionieren.

Delphi-Prism-Quelltext
1:
2:
3:
4:
var i := 5;
var foo : Action<Int32> := a -> Console.WriteLine(i); // ich nehme auch gerne nur System.Action, wenn mir jemand die Syntax für 0 Parameter verrät ^^
i := 6;
foo(42);

Kann doch nicht sein... ich geh lieber mal ins Bett und bin wirklich gespannt auf Antworten.


Robert_G - Sa 26.01.08 11:59
Titel: Re: "Haskell"-Quicksort in Chrome
user profile iconChristian S. hat folgendes geschrieben:
Möchte ich das auch noch als Lambda-Ausdruck machen, geht's nicht mehr:
Recursive Lambdas?
Das wäre sicherlich möglich, momentan geht es leider nicht (Oder doch? :gruebel: )

Der Fehler scheint daher zu rühren, dass Chrome irgendwie den Parameter wegoptimiert...
Wenn man ihn in eine Bogus Local wirft gates:

Delphi-Prism-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
var sort : Func<List<Integer>, List<Integer>>;

with alias := new class(Call := Func<List<Integer>, List<Integer>>(nil)) do
begin
  sort := method(items : List<Integer>): List<Integer>; 
  begin
    var xs := items;
    exit iif(xs.Count = 0
             new List<Integer>(0),
             alias.Call(xs.Where(y -> y < xs[0]).ToList())
                .Concat([xs[0]])
                .Concat(alias.Call(xs.Where(y -> y > xs[0]).ToList())).ToList()
            );       
  end;
 
  alias.Call := sort;
end;  

var l1 := new List<Integer>([21128, -10]);

var l2 := sort(l1);

var asText := l2.Aggregate(new StringBuilder(),
                           (sb, i) -> iif(sb.Length = 0,
                                          sb,
                                          sb.Append(", ")).Append(i));     
Console.WriteLine(asText);