Re: Is it possible to handle 'magic' property assignments a'la PHP?
On 2014-01-07 21:44, H. S. Teoh wrote: If you have a good motivating use case in favor of this addition that can be used in a DIP, I'd vote for it. I'm usually not good at these arguments. I mean, it would be nice to have but I don't have any strong arguments for it. It's just syntax sugar. I like the alias idea, so here's the revised proposal: 1) Argumentless trailing-delegate syntax: // Given this declaration: void foo(alias dg)(); // We can write this: foo { // body } // which will get translated into: foo!({ /* body */ }); 2) With arguments: // Given this declaration: void foo(alias dg, A...)(A args); // Or its non-template equivalent: void foo(alias dg)(A arg1, B arg2, C arg3, ...); // We can write this: foo(a,b,c,...) { // body } // which gets translated into: foo!({ /* body */})(a,b,c,...); 3) With indexing arguments: // Given this declaration: void foo(alias dg, I..., A...)(A args) if (is(typeof(dg(I; // Or its non-template equivalent: void foo(alias dg)(A arg1, B arg2, C arg3, ...) { ... dg(i, j, k); ... } // We can write this: foo(i,j,k,... ; a,b,c,...) { // body } I would prefer to have the delegate arguments last. // which gets translated into: foo!((i,j,k,...) { /* body */ })(a,b,c,...); EXAMPLE: void for_every_other(alias loopBody, R)(R range) if (is(typeof(loopBody(ElementType!R.init { while (!range.empty) { loopBody(range.front); range.popFront(); if (!range.empty) range.popFront(); } } // Prints: // --- // 1 // 3 // 5 // --- for_every_other (i; [1,2,3,4,5,6]) { writeln(i); } If we instead have the delegate argument last UFCS still works: [1,2,3,4,5,6].for_every_other(i) { writeln(i); } Hmm. Actually, your example is more D like. I don't know which I example I like best. I'll see if I can write something down. -- /Jacob Carlborg
Re: dirEntries throws exception on broken symlinks
I reported this here some time ago: http://d.puremagic.com/issues/show_bug.cgi?id=11501 (dup of http://d.puremagic.com/issues/show_bug.cgi?id=8298) and there's a pull request ready, not sure why it isn't being merged On Sun, Jan 5, 2014 at 10:20 PM, dennis wrote: > On Sunday, 5 January 2014 at 21:33:56 UTC, FreeSlave wrote: > >> You must not cast base class to derived class, when you don't know actual >> type (and even if you know exact type it's still bad practice to cast >> instance of more generic type to more specific one). Use multiple catch >> statements instead: >> >> catch(FileException o) >> { >> //handle FileException >> } >> catch(Exception o) >> { >> //handle all other types of exceptions >> } >> >> About dirEntries, you need to move your try/catch statements into loop >> somehow. You probably should save result of dirEntries to variable and then >> make manual loop instead of foreach. Result of dirEntries is lazy, so it >> will not throw exception when you just get it. >> >> It may look like >> >> auto entries = dirEntries(your args); >> while(!entries.empty) >> { >> try >> { >> entry = entries.front; >> //do your stuff >> } >> //"catch" statements >> finally >> { >> entries.popFront(); >> } >> } >> > > Thank you for the quick feedback. Your explanation of the two problems > works for me. >
Re: segfault when using std.parallelism and std.process.executeShell
On Tuesday, 7 January 2014 at 23:12:09 UTC, Ali Çehreli wrote: don't know the original problem but that program works without any problem with the current dmd on github. Works for me on dmd v2.064 (current stable) on Windows.
Re: segfault when using std.parallelism and std.process.executeShell
On 12/12/2013 08:33 PM, Nikhil Padmanabhan wrote: Hi, The following code dies with a segfault : import std.stdio, std.parallelism, std.process; void main() { auto a=["hello","world","goodbye"]; foreach(s; parallel(a,1)) { auto ls=executeShell("echo "~s); writeln(ls.output); } } I don't know the original problem but that program works without any problem with the current dmd on github. Ali both in ldc and dmd. Removing either the "parallel" or running something other than executeShell (eg. just doing a writeln) works, which suggests to me that it's something about the way executeShell is interacting with parallel. Pulling it up in lldb, I get : * thread #2: tid = 0x16738e6, 0x000100039198 test`D3std7process7environFNbNdNeZxPPa + 20, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x000100039198 test`D3std7process7environFNbNdNeZxPPa + 20 Any thoughts on what might be going wrong? Is executeShell somehow not threadsafe? Thanks! -- Nikhil
Re: Foreach loop behaviour and manipulation
On Tue, Jan 07, 2014 at 09:38:34PM +, Binarydepth wrote: > > >or ... for(count=1;count>0 && count<100 || count>999 && > >count<1 || etc...; count++ ) > > That won't work. It's better separate foreach loops. Y'know, this code snippet really reminds me of why Jackson Structured Programming helped me so much. While there are many ways of writing loops, most ways are wrong (some blatantly so, while others only subtly so). Writing a correct loop requires that the structure of the code matches the structure of the problem that it's trying to process. If you're trying to loop over two distinct ranges, 0 to 100 and 999 to 1, then conceptually they are two different operations, and therefore should be mapped to two different loops. Trying to combine them into one usually creates a mess, and even when you get it right, the resulting code is fragile, error-prone, and hard to maintain. I often see code like this: bool first_time = false; for (i=0; i < n; i++) { if (first_time) { do_something(); first_time = true; } if (i+1 == n) { // last time do_something_else(); } do_other_things(); } This kind of code shows a poor mapping of code structure to problem structure, which means it's prone to boundary condition bugs, overlap bugs, and other sorts of problems, not to mention long-range interdependencies that makes the code basically impossible to reuse, and hard to maintain. Consider what the loop is trying to do, by unrolling it. It looks like this: do_something(); do_other_things(); do_other_things(); do_other_things(); ... do_something_else(); do_other_things(); If you "refactor" this, you see that it follows the structure: A --> B (repeat k times) --> C --> B where A = do_something(), B = do_other_things(), and C = do_something_else(). So you see that the repeating part in the structure of the problem is really only with the middle part; A and the final C --> B should be put *outside* the loop body, like this: do_something(); for (i=1; i+1 < n; i++) { // N.B.: loop bounds adjusted do_other_things(); } do_something_else(); do_other_things(); Many programmers, esp. those with C/C++ background, cringe when they see the second call to do_other_things() after the loop body, and they try various ways of putting it inside the loop body -- especially when do_other_things() is a big code block. But actually, this way of writing it is the correct way, because it reflects the structure of the problem more accurately. Putting everything inside one big loop creates a structure conflict with the problem, which has a different structure; this invites people to introduce boolean flags and other such hacks to make things work correctly. But actually, that's just stitching over the symptoms of the deeper problem, which is that the structure of the code fails to correspond with the structure of the problem. By making the structure of the code match the structure of the problem, we eliminate the proliferation of boolean flags and convoluted loop conditions (which are very error-prone and basically impossible to maintain), and the code begins to speak for itself, because just by looking at the structure of the code, you know what's the structure of the problem it's working on. Once the structure is properly sorted out, then we can worry about other things, like do_other_things() being a big copy-n-pasted code block -- which then basically suggests the obvious solution: factor it into a function. A classic example of poor mapping of code structure to problem structure is join(): inserting (n-1) delimiters into a list of n items. I almost always see code like this: foreach (i, e; range) { result.put(e); if (i+1 < range.length) result.put(','); } But let's step back for a moment and look at what's the *real* structure of the problem. Suppose range = [1,2,3,4,5]. Then the desired output is: 1 , 2 , 3 , 4 , 5 Or, more abstractly, if we use 'e' in a generic sense to refer to any item: e , e , e , e , e , e which can be "factored" into the form: (e ,){(n-1) times} e Due to the nature of the range API, however, this does not lend itself to a straightforward implementation (there is no primitive for looping over (n-1) items in a range). So we consider an alternative factorization: e (, e){(n-1) times} This, then, suggests that the first element of the range should be treated specially, which leads to the following code: if (range.empty) return; // boundary case result.put(range.front); range.popFront(); while (!range.empty) { result.put(',');
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Tuesday, 7 January 2014 at 20:38:11 UTC, Craig Dillabaugh wrote: Saves a few lines of code, and looks cooler, it seems that the trivial foreach loop version is very easy: string[] array; foreach (key, value; aa) { array ~= key; array ~= value; } Assuming the return value of `byKey` has a length property, using std.array.array has the benefit of automatically allocating just once for the result, while your proposed alternative will grow on demand, causing several allocations that depend on the number of pairs in `aa`. Of course, Teoh's `aaToArray` can trivially do this too, but the naive loop straight in user code is just that - naive.
Re: Simplest way to create an array from an associative array which its contains keys and values?
On 1/7/14, Craig Dillabaugh wrote: > In other words while: > > auto range = aa.byKey.map!(a => chain(a.only, aa[a].only)); > string[] array = range.join; > > Saves a few lines of code, and looks cooler, it seems that the > trivial foreach loop version is very easy: > > string[] array; > > foreach (key, value; aa) { > array ~= key; > array ~= value; > } OP asked for an array, however the reason I showed the example is because you can get a range that way, which is lazy and will not allocate: auto items = aa.byKey.map!(a => chain(a.only, aa[a].only)).joiner; // no allocations at all writeln(items); So there's a huge difference, as you're saving memory (and CPU time if you don't want to walk through the entire list).
Re: Foreach loop behaviour and manipulation
or ... for(count=1;count>0 && count<100 || count>999 && count<1 || etc...; count++ ) That won't work. It's better separate foreach loops.
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Tuesday, 7 January 2014 at 20:52:40 UTC, H. S. Teoh wrote: On Tue, Jan 07, 2014 at 08:38:10PM +, Craig Dillabaugh wrote: [...] As someone with little experience with functional programming, I am just curious - having browsed through the thread - if the various solutions proposed here would really be considered more 'idiomatic' D. Or if they were posted because the OP asked about avoiding the foreach() loop. In other words while: auto range = aa.byKey.map!(a => chain(a.only, aa[a].only)); string[] array = range.join; Saves a few lines of code, and looks cooler, it seems that the trivial foreach loop version is very easy: string[] array; foreach (key, value; aa) { array ~= key; array ~= value; } [...] Even better, encapsulate this in a function: CommonType!(K,V)[] aaToArray(K,V)(V[K] aa) if (is(CommonType!(V, K))) { typeof(return) result; foreach (key, value; aa) { result ~= key; result ~= value; } return result; } Then you can use it in a single line next time: string[] arr = aaToArray(["a": "aa", "b" : "bb"]); int[] arr = aaToArray([1: 2, 3: 4]); ... // etc. T Yes, I would imagine if this was not a 'one off' operation, you would likely want to create a function. That one looks nice. I posted my question mainly because D advertises itself as a 'multi-paradigm' language. It seems that a number of the more experienced posters on here seem to like functional approaches using the algorithms in std.algorithm. However, it seems to me sometimes the obvious/simple solution that avoids using std.algorithm results in more readable code. So I was curious to know if using std.algorithm functions are generally considered preferable for simple cases like this, or if it is simply a matter of taste. As an aside, the trade-off is even more blatant in C++ where a simple hand-rolled solution often comes out looking so much nicer than the STL alternative.
Re: Foreach loop behaviour and manipulation
On Thursday, 28 November 2013 at 23:45:26 UTC, H. S. Teoh wrote: On Fri, Nov 29, 2013 at 12:36:18AM +0100, Binarydepth wrote: Hi guys I'm having some problems. Calculations are not working as expected and I get segmentation fault. I used the 2.059 version and it runs after compilation on compileonline.com [...] foreach(t; 1..51) { temp=t; t*=20; Modifying the loop variable of a foreach is, in general, a risky move. If you need to make loop indices jump around, you should use a plain for loop instead: for (t=1; t < 51; t++) { // modify t at will, just make sure your loop // condition(s) / loop increments still work correctly. } or, if the loop indices are truly wildly jumping around, use a while loop: t = 1; while (t < 51 /* or whatever condition you may have */) { ... // Do stuff t = ... // compute next index to jump to } T This excersice is an example : "Escriba un programa que determine los números (de cantidad de cifras par) divisores de 11 aplicando el siguiente concepto: cuando la suma de los dígitos alternos del número son iguales, ese número es exactamente divisible por once. Por ejemplo 5841: 5 + 4 = 8 + 1, por lo tanto el número 5841 es divisible por once." The important part is "los números (de cantidad de cifras par)" The number of pair digits 10 to 99, 1000 to , 10 to 99, etc... I immediately thought of this thread. Surely you can use a series of if inside the loop that will make it jump the undesired numbers. or ... for(count=1;count>0 && count<100 || count>999 && count<1 || etc...; count++ )
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Tue, Jan 07, 2014 at 08:38:10PM +, Craig Dillabaugh wrote: [...] > As someone with little experience with functional programming, I am > just curious - having browsed through the thread - if the various > solutions proposed here would really be considered more 'idiomatic' > D. Or if they were posted because the OP asked about avoiding the > foreach() loop. > > In other words while: > > auto range = aa.byKey.map!(a => chain(a.only, aa[a].only)); > string[] array = range.join; > > Saves a few lines of code, and looks cooler, it seems that the > trivial foreach loop version is very easy: > > string[] array; > > foreach (key, value; aa) { > array ~= key; > array ~= value; > } [...] Even better, encapsulate this in a function: CommonType!(K,V)[] aaToArray(K,V)(V[K] aa) if (is(CommonType!(V, K))) { typeof(return) result; foreach (key, value; aa) { result ~= key; result ~= value; } return result; } Then you can use it in a single line next time: string[] arr = aaToArray(["a": "aa", "b" : "bb"]); int[] arr = aaToArray([1: 2, 3: 4]); ... // etc. T -- Real men don't take backups. They put their source on a public FTP-server and let the world mirror it. -- Linus Torvalds
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On Tue, Jan 07, 2014 at 09:18:48PM +0100, Jacob Carlborg wrote: > On 2014-01-07 16:58, H. S. Teoh wrote: > > >Y'know, I've always wanted "trailing delegate syntax": > > > > func(x, y, z; p, q, r) { > > // body > > } > > > >gets translated into: > > > > func(p, q, r, (x, y, z) => /* body */); > > > >Since we already have UFCS, which translates a leading fragment into > >the first argument (x.func(y) --> func(x,y)), it seems perfectly > >reasonable to do something with the final argument too, like the > >above. > > > >This would allow one to implement, for example, foreach_reverse as a > >library function instead of a language keyword: > > > > void foreach_reverse(I, R)(R range, void delegate(I) dg) > > { > > ... > > dg(idx); > > ... > > } > > > > // Gets translated to: > > // foreach_reverse(range, (uint i) => /* body */); > > foreach_reverse (uint i; range) { > > ... // body > > } > > > > // And you can use UFCS too: > > range.foreach_reverse(uint i) { > > ... // body > > } > > Exactly, that's what it is for. Perhaps supporting an alias > parameter would be good as well, since those are inlined: > > void foo (alias dg) (); > > foo { > // body > } > > Translated to: > > foo!({ > // body > }); > > >I'm not holding my breath on this one, though. It's a rather big > >change and ultimately is just syntactic sugar. Maybe it can go on the > >list of features for D3... ;-) > > I've brought this up before. If I recall correctly, it didn't was > that much resistance as one could think. Although this was before we > had the lambda syntax. [...] If you have a good motivating use case in favor of this addition that can be used in a DIP, I'd vote for it. I like the alias idea, so here's the revised proposal: 1) Argumentless trailing-delegate syntax: // Given this declaration: void foo(alias dg)(); // We can write this: foo { // body } // which will get translated into: foo!({ /* body */ }); 2) With arguments: // Given this declaration: void foo(alias dg, A...)(A args); // Or its non-template equivalent: void foo(alias dg)(A arg1, B arg2, C arg3, ...); // We can write this: foo(a,b,c,...) { // body } // which gets translated into: foo!({ /* body */})(a,b,c,...); 3) With indexing arguments: // Given this declaration: void foo(alias dg, I..., A...)(A args) if (is(typeof(dg(I; // Or its non-template equivalent: void foo(alias dg)(A arg1, B arg2, C arg3, ...) { ... dg(i, j, k); ... } // We can write this: foo(i,j,k,... ; a,b,c,...) { // body } // which gets translated into: foo!((i,j,k,...) { /* body */ })(a,b,c,...); EXAMPLE: void for_every_other(alias loopBody, R)(R range) if (is(typeof(loopBody(ElementType!R.init { while (!range.empty) { loopBody(range.front); range.popFront(); if (!range.empty) range.popFront(); } } // Prints: // --- // 1 // 3 // 5 // --- for_every_other (i; [1,2,3,4,5,6]) { writeln(i); } EXTENDED EXAMPLE: void for_every_other(alias loopBody, R)(R range) if (is(typeof(loopBody(size_t.init, ElementType!R.init { size_t i=0; while (!range.empty) { loopBody(i, range.front); range.popFront(); if (!range.empty) { range.popFront(); i += 2; } } } // Prints: // --- // 0: "a" // 2: "c" // 4: "e" // --- for_every_other (i, j; ["a", "b", "c", "d", "e", "f"]) { writefln("%s: %s", i, j); } T -- Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG
Re: Simplest way to create an array from an associative array which its contains keys and values?
On Friday, 3 January 2014 at 17:38:16 UTC, Gary Willoughby wrote: Simplest way to create an array from an associative array which its contains keys and values? For example if i have an associative array like this: ["one":"1", "two":"2"] What's the easiest way to create a dynamic array that looks like this: ["one", "1", "two", "2"] I know it can be done via a loop, but is there a more idiomatic way to achieve this? As someone with little experience with functional programming, I am just curious - having browsed through the thread - if the various solutions proposed here would really be considered more 'idiomatic' D. Or if they were posted because the OP asked about avoiding the foreach() loop. In other words while: auto range = aa.byKey.map!(a => chain(a.only, aa[a].only)); string[] array = range.join; Saves a few lines of code, and looks cooler, it seems that the trivial foreach loop version is very easy: string[] array; foreach (key, value; aa) { array ~= key; array ~= value; }
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On 2014-01-07 16:58, H. S. Teoh wrote: Y'know, I've always wanted "trailing delegate syntax": func(x, y, z; p, q, r) { // body } gets translated into: func(p, q, r, (x, y, z) => /* body */); Since we already have UFCS, which translates a leading fragment into the first argument (x.func(y) --> func(x,y)), it seems perfectly reasonable to do something with the final argument too, like the above. This would allow one to implement, for example, foreach_reverse as a library function instead of a language keyword: void foreach_reverse(I, R)(R range, void delegate(I) dg) { ... dg(idx); ... } // Gets translated to: // foreach_reverse(range, (uint i) => /* body */); foreach_reverse (uint i; range) { ... // body } // And you can use UFCS too: range.foreach_reverse(uint i) { ... // body } Exactly, that's what it is for. Perhaps supporting an alias parameter would be good as well, since those are inlined: void foo (alias dg) (); foo { // body } Translated to: foo!({ // body }); I'm not holding my breath on this one, though. It's a rather big change and ultimately is just syntactic sugar. Maybe it can go on the list of features for D3... ;-) I've brought this up before. If I recall correctly, it didn't was that much resistance as one could think. Although this was before we had the lambda syntax. -- /Jacob Carlborg
Re: dub and ddox
Also, I cannot find any documentation on ddox arguments (ddoxFilterArgs). Is this currently not available? I had to look through the source code and vibe.d to figure them out. Regards, Kelet
dub and ddox
Hello, I'm working on a library, and I'm trying to write the documentation with Sönke's ddox software[1]. As I understand, it works with the Ddoc documentation format[2]. The first problem I came across is that documented unit tests weren't being converted into examples like in [2]. I came to realize that you have to specifically enable it in package.json, like so: "-ddoxFilterArgs": [ "--unittest-examples" ] Now my problem is styling it. While it looks decent, it is just plain white. I noticed there were some questions about styling it before, but I mainly want it so that if I type `dub build --build=ddox` it will generate my styled documentation. Or at least some process similar to this. I think bootDoc[3] looks pretty good out of the box, but I don't think it works with ddox. I'd like to hear any other misc. comments about using ddox (particularly with dub). I was hoping there would be a few alternative styles already made under a nice license that I could tweak. [1]: https://github.com/rejectedsoftware/ddox [2]: http://dlang.org/ddoc.html [3]: https://github.com/JakobOvrum/bootDoc
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On Tue, Jan 07, 2014 at 03:35:43PM +0100, Jacob Carlborg wrote: > On 2014-01-07 13:22, Philippe Sigaud wrote: > > >What about: > > > >void loop(void delegate() dg); > > > >loop({ > >... > > > >}); > > > >Since any block is a void delegate(). > > That's what we have now, and that doesn't look like a built-in > statement ;) [...] Y'know, I've always wanted "trailing delegate syntax": func(x, y, z; p, q, r) { // body } gets translated into: func(p, q, r, (x, y, z) => /* body */); Since we already have UFCS, which translates a leading fragment into the first argument (x.func(y) --> func(x,y)), it seems perfectly reasonable to do something with the final argument too, like the above. This would allow one to implement, for example, foreach_reverse as a library function instead of a language keyword: void foreach_reverse(I, R)(R range, void delegate(I) dg) { ... dg(idx); ... } // Gets translated to: // foreach_reverse(range, (uint i) => /* body */); foreach_reverse (uint i; range) { ... // body } // And you can use UFCS too: range.foreach_reverse(uint i) { ... // body } I'm not holding my breath on this one, though. It's a rather big change and ultimately is just syntactic sugar. Maybe it can go on the list of features for D3... ;-) T -- Famous last words: I wonder what will happen if I do *this*...
Re: libphobos.so and loading libraries at runtime
On Sunday, 5 January 2014 at 20:47:44 UTC, FreeSlave wrote: But why does dmd use static linking by default? Is shared version of phobos still experimental? It is. It works pretty good in practice but Martin wanted to improve provided utilities for library/symbol loading before announcing it as released AFAIR.
Re: libphobos.so and loading libraries at runtime
On Sunday, 5 January 2014 at 20:47:44 UTC, FreeSlave wrote: import core.runtime; int main() { Runtime.loadLibrary("does not care"); Runtime.unloadLibrary(null); return 0; } When I try to compile this code with 'dmd main.d', I get errors main.o: In function `_D4core7runtime7Runtime17__T11loadLibraryZ11loadLibraryFxAaZPv': main.d:(.text._D4core7runtime7Runtime17__T11loadLibraryZ11loadLibraryFxAaZPv+0x4d): undefined reference to `rt_loadLibrary' main.o: In function `_D4core7runtime7Runtime19__T13unloadLibraryZ13unloadLibraryFPvZb': main.d:(.text._D4core7runtime7Runtime19__T13unloadLibraryZ13unloadLibraryFPvZb+0x8): undefined reference to `rt_unloadLibrary' But it's built without errors when I separate compile and link parts: dmd -c main.d gcc main.o -lphobos2 -o main I checked libraries with nm utility and actually found no such symbols in static version of libphobos. But shared one has these symbols. Well, I'm aware of that runtime loading requires shared version of phobos2 to avoid duplicating of D runtime. But why does dmd use static linking by default? Is shared version of phobos still experimental? Anyway we need some remarks in documentation about the lack of these functions in static version of phobos. This seems like a weird change if intentional, since the function is publicly declared. I'd file a bug report.
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On 2014-01-07 13:22, Philippe Sigaud wrote: What about: void loop(void delegate() dg); loop({ ... }); Since any block is a void delegate(). That's what we have now, and that doesn't look like a built-in statement ;) -- /Jacob Carlborg
Re: Is it possible to handle 'magic' property assignments a'la PHP?
On Tue, Jan 7, 2014 at 8:50 AM, Jacob Carlborg wrote: > I would like to have that in D as well, but with braces instead: > > void loop (void delegate () dg); > > loop { > // endless loop > } What about: void loop(void delegate() dg); loop({ ... }); Since any block is a void delegate().