Gebt doch endlich mal richtige Gründe gegen die Sprache D an!



  • Hab mal versucht, n kleines Programm zu schreiben. Funktionieren tuts zumindest bei mir, keine Ahnung was da bei ideone nicht passt.
    http://ideone.com/JZLdok

    1. Ist das idiomatisches D? Wenn nicht, was wuerde man anders machen?
    2. Wird hier alles korrekt aufgeraeumt? Wenn nicht, was muss ich dafuer tun?
    3. Wie schreib ich das Programm ohne GC?


  • Kellerautomat schrieb:

    Hab mal versucht, n kleines Programm zu schreiben. Funktionieren tuts zumindest bei mir, keine Ahnung was da bei ideone nicht passt.
    http://ideone.com/JZLdok

    1. Ist das idiomatisches D? Wenn nicht, was wuerde man anders machen?
    2. Wird hier alles korrekt aufgeraeumt? Wenn nicht, was muss ich dafuer tun?
    3. Wie schreib ich das Programm ohne GC?
    1. Nein. Siehe Beispiele. Exception handling wird in D anders gemacht. enum > immutable > const. Für Compiletime-Konstante immer enum, sonst immutable. const bedeutet "hier read-only, andere Programmteile dürfen aber den Status verändern". Man kann das Problem auch mit Ranges arbeiten, aber das ist fürs erste zu viel.
    2. Ja.
    3. http://forum.dlang.org/thread/kjo7id$22jk$1@digitalmars.com?page=1 Den GC umgeht man in der Praxis dadurch, dass man das Memory Management selber in die Hand nimmt. Und soo schlecht ist ein GC auch nicht.
    4. Die typischen D-IDEs sind Emacs, Vim und MicroEmacs.


  • Alles klar, mein Gedankenproblem war, dass ich irgendwie mehrere Rekursionen parallel machen wollte, was so recht natürlich nicht funktioniert. Jetzt gehe ich anders an die Sache ran... Erstmal baue ich eine Liste aus Odd-Even-Merges, die sequentiell abgearbetet werden muss, und für jede dieser Listen implementiere ich die parallele Rekursion dadurch, dass Ich einen Rekursionsschritt mache und die Ergebnisse der einzelnen Merges "interleave". Da die Teilbäume ja gleich aussehen im Falle von 2^N, sind die Bäume ja exakt gleichartig.

    module main;
    
    import std.stdio;
    import std.algorithm;
    import std.conv;
    
    struct merge_args {
    	int low;
    	int high;
    };
    
    struct cas_args {
    	int arg0;
    	int arg1;
    };
    
    cas_args[] GenerateCasList( int lo, int hi, int r )
    {
    	int step = r*2;
    	if( step < hi-lo ) {
    		cas_args[] list1 = GenerateCasList( lo, hi, step );
    		cas_args[] list2 = GenerateCasList( lo+r, hi, step );
    		cas_args[] interleaved;
    
    		for( int i=0; i<list1.length; ++i ) {
    			interleaved ~= list1[i];
    			interleaved ~= list2[i];
    		}
    
    		for( int i=lo+r; i<hi-r; i += step ) {
    			interleaved ~= cas_args( i, i+r );
    		}
    
    		return interleaved;
    	} else {
    		return [ cas_args( lo, lo+r ) ];
    	}
    }
    
    cas_args[] GenerateCasListFromMergeSet( ref merge_args[] merge_set )
    {
    	cas_args[] result;
    
    	cas_args[][] merge_cas_lists;
    	for( int i=0; i<merge_set.length; ++i ) {
    		merge_cas_lists ~= GenerateCasList( merge_set[i].low, merge_set[i].high, 1 );
    	}
    
    	for( int i=0; i<merge_cas_lists[0].length; ++i ) {
    		for( int j=0; j<merge_cas_lists.length; ++j ) {
    			result ~= merge_cas_lists[j][i];
    		}
    	}
    
    	return result;
    }
    
    cas_args[] GenerateCasListFromMergeSets( ref merge_args[][] merge_sets )
    {
    	cas_args[] result;
    	for( int i=0; i<merge_sets.length; ++i ) {
    		result ~= GenerateCasListFromMergeSet( merge_sets[i] );
    	}
    	return result;
    }
    
    merge_args[][] GenerateMergeSets( int array_size )
    {
    	merge_args[][] merge_sets;
    
    	for( int stride = array_size; stride > 1; stride /= 2 ) {
    		merge_args[] current_set;
    
    		for( int i=0; i<array_size; i += stride ) {
    			current_set ~= merge_args( i, i+stride-1 );
    		}
    		merge_sets = current_set ~ merge_sets;
    	}
    
    	return merge_sets;
    }
    
    string GenerateNetworkMixin( string arr, string op, int size )
    {
    	merge_args[][] merge_sets = GenerateMergeSets( size );
    	cas_args[] cas_list = GenerateCasListFromMergeSets( merge_sets  );
    
    	string result;
    	for( int i=0; i<cas_list.length; ++i ) {
    		string arg0 = arr~"["~to!string(cas_list[i].arg0)~"]";
    		string arg1 = arr~"["~to!string(cas_list[i].arg1)~"]";
    		result ~= "if("~arg0~op~arg1~") swap("~arg0~","~arg1~");\n";
    	}
    
    	return result;
    }
    
    int main(string[] argv)
    {
    	int array[8] = [ 4,6,1,8,3,1,6,5 ];
    	mixin( GenerateNetworkMixin( "array", ">", array.length ) );
    	write( GenerateNetworkMixin( "array", ">", array.length ) );
    	for( int i=0; i<array.length; ++i ) write( array[i], "," );
    	stdout.flush();
    	return 0;
    }
    

    Mit der Ausgabe:

    if(array[0]>array[1]) swap(array[0],array[1]);
    if(array[2]>array[3]) swap(array[2],array[3]);
    if(array[4]>array[5]) swap(array[4],array[5]);
    if(array[6]>array[7]) swap(array[6],array[7]);
    if(array[0]>array[2]) swap(array[0],array[2]);
    if(array[4]>array[6]) swap(array[4],array[6]);
    if(array[1]>array[3]) swap(array[1],array[3]);
    if(array[5]>array[7]) swap(array[5],array[7]);
    if(array[1]>array[2]) swap(array[1],array[2]);
    if(array[5]>array[6]) swap(array[5],array[6]);
    if(array[0]>array[4]) swap(array[0],array[4]);
    if(array[1]>array[5]) swap(array[1],array[5]);
    if(array[2]>array[6]) swap(array[2],array[6]);
    if(array[3]>array[7]) swap(array[3],array[7]);
    if(array[2]>array[4]) swap(array[2],array[4]);
    if(array[3]>array[5]) swap(array[3],array[5]);
    if(array[1]>array[2]) swap(array[1],array[2]);
    if(array[3]>array[4]) swap(array[3],array[4]);
    if(array[5]>array[6]) swap(array[5],array[6]);
    1,1,3,4,5,6,6,8,
    


  • hreadv schrieb:

    Exception handling wird in D anders gemacht.

    Ich hab dazu nicht viel gefunden. Koenntest du etwas konkreter werden?

    hreadv schrieb:

    enum > immutable > const. Für Compiletime-Konstante immer enum, sonst immutable. const bedeutet "hier read-only, andere Programmteile dürfen aber den Status verändern".

    Wenn man das also in C++ uebrsetzen wuerde, stimmt das so in etwa?
    enum = constexpr
    immutable = const daten
    const = const view

    hreadv schrieb:

    Man kann das Problem auch mit Ranges arbeiten, aber das ist fürs erste zu viel.

    Wuerde mich schon interessieren. 😉

    hreadv schrieb:

    1. http://forum.dlang.org/thread/kjo7id$22jk$1@digitalmars.com?page=1 Den GC umgeht man in der Praxis dadurch, dass man das Memory Management selber in die Hand nimmt. Und soo schlecht ist ein GC auch nicht.

    Mit anderen Worten: Ohne GC ist D quasi nutzlos, weil man sich Stdlib-Ersatz schreiben muss.

    Ich hab das Programm mal ueberarbeitet: http://ideone.com/hYLa7k
    Besser?



  • Die Sprache ist darauf ausgelegt, einen GC zu verwenden. Dir ist es aber freigestellt, für gewisse Instanzen keinen zu verwenden, nur dann musst Du halt selber auf die Lebenszeiten achten und auf ein paar weitere kleine Details, damit der GC auf seinem Working-Set zurande kommt. Alles nötige für die Custom-Allokatoren Deiner Klassen kannst wahrscheinlich per Template-Mixin reinmixen, sodass das nur einmal-Aufwand ist. Wenn Du aber gar keinen GC verwenden willst und die Stdlib das gefälligst auch nicht tun soll, dann ist es wohl nicht die richtige Sprache.
    Aber selbst in C++ verwendet man Pools um Allokationen zu vermeiden, wenn's wirklich um die Wurst geht, also sehe ich da den Nachteil noch nicht so stark. Wenn man jetzt aber die Sprache auseinander nimmt wegen des GCs, dann kann man auch gleich sagen: Ich will niemals GC, basta, D ist nix für mich, dafür wurstel ich lieber mit ekligen Templates und anderer Grütze rum.



  • Wobei wahrscheinlich für SIMD-Befehle der Odd-Even-Transposition-Algorithmus besser geeignet ist? Ersteinmal ist der im Aufbau viel einfacher und zweitens kann man ja bei SIMD keine Hardware-Einheiten sparen, dadurch dass auf einer Stufe weniger los ist - während man aber im Falle von 8 Elementen mehr sequenzielle Stufen abarbeiten muss.



  • Ja nun, es ist schon peinlich, in wievielen Arten und Weisen ich den Algorithmus missverstanden habe, als ich ihn aus dem Python-Code reverse-engineeren wollte und mir das Bild auf Wikipedia angeschaut habe. Jetzt habe ich mich mal mit dem Algorithmus eingehender beschäftigt und siehe da, es lässt sich doch effizienter veranstalten, das ganze. Vielleicht interessiert sich ja volkard noch dafür?

    http://pastebin.com/txwS2cBZ

    Ansonsten ignorieren & weitergehen 😉



  • Grumpf, Zeile 122 sollte da nicht sein... -> http://pastebin.com/vZzu8x6s



  • jetzt setzt Facebook auch langsam D ein das könnte die Sprache populärer machen


Anmelden zum Antworten