Re: How to delete dynamic array ?
Ilya Yaroshenko: case 1: delete ar; It's deprecated. case 4: ar = null;// (assumed that ar is only one pointer to the same array) It's the simpler way. How to free memory to the system immediately? What is your use case? Bye, bearophile
Re: How to delete dynamic array ?
Answer will make more sense if ar is assumed to be any heap-allocated object, not just dynamic array. On Monday, 30 December 2013 at 06:52:20 UTC, Ilya Yaroshenko wrote: case 1: delete ar; Deprecated. Used to call destructor and GC.free after that case 2: ar.destroy(); Current solution to free resources in deterministic way. Calls destructor and sets `ar` to init state so that it can be collected by GC at some unknown point later. case 3: GC.free(ar.ptr); Marks memory as freed in GC. Unsafe and discouraged because there can still be references pointing at it. case 4: ar = null;// (assumed that ar is only one pointer to the same array) Simply cleans the reference to an object. If it was the only reference, it will be destroyed and freed upon next GC cycle. What is the difference? How to free memory to the system immediately? GC.free However, if you want deterministic deallocation it makes more sense to use C malloc or custom allocators as GC tends to run faster if it is aware of less memory.
Re: How to delete dynamic array ?
On Monday, 30 December 2013 at 06:52:20 UTC, Ilya Yaroshenko wrote: case 1: delete ar; case 2: ar.destroy(); case 3: GC.free(ar.ptr); case 4: ar = null;// (assumed that ar is only one pointer to the same array) What is the difference? How to free memory to the system immediately? It depends on how it is allocated. The `delete` operator is deprecated, so it is never appropriate. For GC memory (memory allocated with `new`, the concatenation operators or array literals) then you should just `null` any reference that is no longer used, leaving it to the GC to collect the memory when it sees fit. This guarantees memory safety, which is the primary purpose of a memory garbage collector. If you really, really must free a chunk of GC memory *right now*, you can use GC.free, but you lose any guarantee of memory safety. If you can't think of a reason your code needs to do this, then your code probably doesn't need it. If the array is allocated from a non-GC heap, such as the C heap, use the corresponding freeing function (C heap using `malloc` + `free`). `destroy` is for running destructors on, and then invalidating, instances of user-defined types (UDTs). For generic code purposes, you can use it on non-UDTs, in which case it will just invalidate them. Values invalidated with `destroy` must not be used after invalidation - it is a logic error. What it means by invalidation is up to the implementation, but it guarantees that it won't free memory. Currently, it zero-blasts the value (which may be different from the value's default initializer).
Recursive lambda functions?
Hello! Is there any ability to lambda function call itself? Is it correct feature for D? Best Regards, Ilya
Re: Recursive lambda functions?
Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com
Re: Recursive lambda functions?
On Monday, 30 December 2013 at 11:23:39 UTC, Ilya Yaroshenko wrote: Hello! Is there any ability to lambda function call itself? Is it correct feature for D? Best Regards, Ilya Well it's possible to do this (sort of). //You could for instance define the Factorial function like this. int delegate(int) f; f = (int x) = x 0 ? f(x - 1) * x : 1; It's not very pretty and offers little compared to just make it a normal function. void f(int x) { return x 0 ? f(x - 1) * x : 1; }
Debug/reduce stack overflow in DMD on Windows
I've ported one of my projects[1] from D1 to D2 and it works perfectly fine on Posix. Now when I try to compile the code on Windows I get a stack overflow. I really suck at Windows development, I don't even know where to start. Which debugger should I use that can handle the debug format DMD is compiled with? [1] https://github.com/jacob-carlborg/dvm/tree/master -- /Jacob Carlborg
Re: Possible bug - should the following code cause an access violation exception?
On 12/29/2013 10:38 PM, Afshin wrote: module test; class Foo { public static ulong next = 0; public static ulong getNext() { return next++; } } void main() { Foo.getNext(); } /* The next++ is the culprit. Using a ++next does not throw an exception. */ Must have already been fixed. No problem on git head. Ali
Re: Debug/reduce stack overflow in DMD on Windows
Am 30.12.2013 14:04, schrieb Jacob Carlborg: I've ported one of my projects[1] from D1 to D2 and it works perfectly fine on Posix. Now when I try to compile the code on Windows I get a stack overflow. I really suck at Windows development, I don't even know where to start. Which debugger should I use that can handle the debug format DMD is compiled with? [1] https://github.com/jacob-carlborg/dvm/tree/master Compile in 64-bit and use Visual Studio or Visual Studio Express to debug the application. If you want to compile in 32-bit you will need to run cv2pdb on the generated exectuable before debugging with visual studio. cv2pdb is part of VisualD which I recommend using for any windows development. Kind Regards Benjamin Thaut
Re: boilerplate generation
On Monday, 30 December 2013 at 04:35:34 UTC, Dicebot wrote: It can be forced by pragma(mangle) though. Updated code: [...] Never heard of pragma(mangle)! Very useful. What role does it play in D? Is it guaranteed implemented on x86 or amd64? Thanks for the answer, very nice.
Re: boilerplate generation
On Monday, 30 December 2013 at 17:33:13 UTC, Carl Sturtivant wrote: On Monday, 30 December 2013 at 04:35:34 UTC, Dicebot wrote: It can be forced by pragma(mangle) though. Updated code: [...] Never heard of pragma(mangle)! Very useful. What role does it play in D? Is it guaranteed implemented on x86 or amd64? Thanks for the answer, very nice. It's unrelated to the target architecture, it's just for naming. See dlang.org/abi.html
module std.regex
Hello, when I try to run following code: import std.stdio; import std.net.curl; void main() { writeln(dlang.org); } I get following error: Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64': The module 'std.regex' is already defined in './maina'. Segmentation fault (core dumped) Somewhere I read that this should fix it: - Make ModuleInfos immutable, which is something we should do anyhow. But what are ModuleInfos ? Where I can find them and what exactly to do with them?
Slices, appending to arbitrary position
This simple example: string[] a; a[10] = hello; Gives me: core.exception.RangeError: Range violation I know about this way: string[] a; a = new string[11]; a[10] = hello; But what if i need do this many times with the same array like this: a[10] = a; ... a[1] = b; .. a[1000] = c; If i will call a = new string[11] all those many times, isn't this will be inefficient ? Also it will clear all previous contents of a, which is not suitable.
Re: Slices, appending to arbitrary position
On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote: This simple example: string[] a; a[10] = hello; Gives me: core.exception.RangeError: Range violation I know about this way: string[] a; a = new string[11]; a[10] = hello; But what if i need do this many times with the same array like this: a[10] = a; ... a[1] = b; .. a[1000] = c; Does it *need* to be an array for some reason? If so, resize the array prior. Something like: // index is the position you're changing // value is the value you're changing to if(a.length = index) { a.length = index+1; } a[index] = value; If you're just mapping integers to strings, then you're probably looking for an associative array: http://dlang.org/hash-map.html This is probably more like what you actually want: string[size_t] a; a[1] = works fine; a[10] = also works fine; isn't this will be inefficient ? Yes. Resizing the array many times is very inefficient. Either use an associative array or know ahead of time what your array's length needs to be (or, at least, what it will likely need to be).
Re: Slices, appending to arbitrary position
Dfr: string[] a; a[10] = hello; Gives me: core.exception.RangeError: Range violation Because 'a' has length 0, so the position with index 11 doesn't exists in the array. By the way, this is not an appending, it's a (failed) assignment. I know about this way: string[] a; a = new string[11]; a[10] = hello; But what if i need do this many times with the same array like this: a[10] = a; ... a[1] = b; .. a[1000] = c; If i will call a = new string[11] all those many times, isn't this will be inefficient ? Also it will clear all previous contents of a, which is not suitable. If you need to assign strings randomly then a good solution is to use an associative array, that is a quite different data structure: string[int] aa; aa[10] = a; aa[1] = b; aa[1000] = c; As alternative if you want a normal dynamic array, you can resize it: string[int] a; a.length = max(a.length, 10 + 1); a[10] = a; a.length = max(a.length, 1 + 1); a[1] = b; a.length = max(a.length, 1000 + 1); a[1000] = c; Bye, bearophile
Re: Slices, appending to arbitrary position
On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote: This simple example: string[] a; a[10] = hello; Gives me: core.exception.RangeError: Range violation I know about this way: string[] a; a = new string[11]; a[10] = hello; But what if i need do this many times with the same array like this: a[10] = a; ... a[1] = b; .. a[1000] = c; If i will call a = new string[11] all those many times, isn't this will be inefficient ? Also it will clear all previous contents of a, which is not suitable. Arrays are contiguous chunks of memory. If you wanted to store c as the 1000th element in an array of strings, that array needs to have room for 1000 elements. Perhaps what you want is an associative array: string[uint] aa; aa[10] = a; aa[1] = b; aa[1000] = c; writeln(aa[10], aa[1], aa[1000]);
Re: module std.regex
On Monday, 30 December 2013 at 18:08:42 UTC, Benji wrote: Hello, when I try to run following code: import std.stdio; import std.net.curl; void main() { writeln(dlang.org); } I get following error: Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64': The module 'std.regex' is already defined in './maina'. Segmentation fault (core dumped) Somewhere I read that this should fix it: - Make ModuleInfos immutable, which is something we should do anyhow. But what are ModuleInfos ? Where I can find them and what exactly to do with them? Which compiler/version?
Re: Slices, appending to arbitrary position
Thank you for replies, i think here i can use assoc array, but sometimes it is not suitable because it is not preserve order. On Monday, 30 December 2013 at 18:19:54 UTC, Dfr wrote: This simple example: string[] a; a[10] = hello; Gives me: core.exception.RangeError: Range violation I know about this way: string[] a; a = new string[11]; a[10] = hello; But what if i need do this many times with the same array like this: a[10] = a; ... a[1] = b; .. a[1000] = c; Does it *need* to be an array for some reason? If so, resize the array prior. Something like: // index is the position you're changing // value is the value you're changing to if(a.length = index) { a.length = index+1; } a[index] = value; If you're just mapping integers to strings, then you're probably looking for an associative array: http://dlang.org/hash-map.html This is probably more like what you actually want: string[size_t] a; a[1] = works fine; a[10] = also works fine; isn't this will be inefficient ? Yes. Resizing the array many times is very inefficient. Either use an associative array or know ahead of time what your array's length needs to be (or, at least, what it will likely need to be).
Re: module std.regex
On Monday, 30 December 2013 at 18:36:24 UTC, John Colvin wrote: On Monday, 30 December 2013 at 18:08:42 UTC, Benji wrote: Hello, when I try to run following code: import std.stdio; import std.net.curl; void main() { writeln(dlang.org); } I get following error: Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64': The module 'std.regex' is already defined in './maina'. Segmentation fault (core dumped) Somewhere I read that this should fix it: - Make ModuleInfos immutable, which is something we should do anyhow. But what are ModuleInfos ? Where I can find them and what exactly to do with them? Which compiler/version? DMD 2.064-2 64bit, Ubuntu 13.10
Re: Slices, appending to arbitrary position
On Mon, Dec 30, 2013 at 06:40:24PM +, Dfr wrote: Thank you for replies, i think here i can use assoc array, but sometimes it is not suitable because it is not preserve order. Maybe you can use std.container.RedBlackTree instead? That will preserve order (but at the cost of asymptotically slower lookups / insertions). T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Re: module std.regex
30-Dec-2013 22:08, Benji пишет: Hello, when I try to run following code: import std.stdio; import std.net.curl; void main() { writeln(dlang.org); } I get following error: Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64': The module 'std.regex' is already defined in './maina'. Segmentation fault (core dumped) It's a bug in 2.064-2 when using shared library. You as end user can't do much about it - wait for the next release where it should be fixed or use static linking for the moment. Somewhere I read that this should fix it: - Make ModuleInfos immutable, which is something we should do anyhow. This is part of core developers discussion and isn't something easily tweaked (else it would've been already fixed). -- Dmitry Olshansky
Re: module std.regex
On Monday, 30 December 2013 at 19:27:43 UTC, Dmitry Olshansky wrote: 30-Dec-2013 22:08, Benji пишет: Hello, when I try to run following code: import std.stdio; import std.net.curl; void main() { writeln(dlang.org); } I get following error: Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.64': The module 'std.regex' is already defined in './maina'. Segmentation fault (core dumped) It's a bug in 2.064-2 when using shared library. You as end user can't do much about it - wait for the next release where it should be fixed or use static linking for the moment. Somewhere I read that this should fix it: - Make ModuleInfos immutable, which is something we should do anyhow. This is part of core developers discussion and isn't something easily tweaked (else it would've been already fixed). Thanks! Could be downgrading to 2.063 the solution?
Re: boilerplate generation
On Monday, 30 December 2013 at 17:46:57 UTC, John Colvin wrote: It's unrelated to the target architecture, it's just for naming. See dlang.org/abi.html Apologies, I was perhaps unclear. I'm just wondering if pragma(mangle) is guaranteed to be implemented, so I can safely put it in portable D. It's not mentioned in http://dlang.org/pragma.html
Re: Debug/reduce stack overflow in DMD on Windows
On 2013-12-30 17:19, Benjamin Thaut wrote: Compile in 64-bit and use Visual Studio or Visual Studio Express to debug the application. If you want to compile in 32-bit you will need to run cv2pdb on the generated exectuable before debugging with visual studio. cv2pdb is part of VisualD which I recommend using for any windows development. I'll give that a try, thanks. -- /Jacob Carlborg
Re: boilerplate generation
On Monday, 30 December 2013 at 20:04:00 UTC, Carl Sturtivant wrote: Apologies, I was perhaps unclear. I'm just wondering if pragma(mangle) is guaranteed to be implemented, so I can safely put it in portable D. It's not mentioned in http://dlang.org/pragma.html Nature of reference compiler is that anything implemented there is approved as part of spec. I guess one implementing it just forgot to add matching documentation entry as it is relatively new addition. https://d.puremagic.com/issues/show_bug.cgi?id=11846
Re: Recursive lambda functions?
On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote: Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com This is not lambda =( I want something like enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function
A better way to write this function? (style question)
I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing?
Re: Recursive lambda functions?
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko wrote: I want something like enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function That isn't supported in D. And cases where this would be useful are too rare to add complexity to the language. Just use a regular function, it's not much more code.
Re: Recursive lambda functions?
On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote: On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote: Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com This is not lambda =( I want something like enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function enum factorial5=(function int(a)=a==0?1:a*__traits(parent,{})(a-1))(5); (In D, you need to specify the return type for a recursive function declaration. If one doesn't here, DMD crashes, which is a bug. https://d.puremagic.com/issues/show_bug.cgi?id=11848)
Re: A better way to write this function? (style question)
On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing? A few points: by declaring a new string and appending to it you are risking a lot of allocations. Either use std.array.appender or allocate the array with the correct size at the beginning. using .array on the end of the ufcs chain is yet another allocation. It can be avoided using std.algorithm.copy to copy the result back in to 'line' In my opinion the whole API would be better as range-based: auto splitSentence(R)(R input) if(isInputRange!R) { return input .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : c.toLower) .splitter!(' ') .filter!(a = !(a.empty)); }
Re: Debug/reduce stack overflow in DMD on Windows
On Monday, 30 December 2013 at 13:04:38 UTC, Jacob Carlborg wrote: I've ported one of my projects[1] from D1 to D2 and it works perfectly fine on Posix. Now when I try to compile the code on Windows I get a stack overflow. I really suck at Windows development, I don't even know where to start. Which debugger should I use that can handle the debug format DMD is compiled with? [1] https://github.com/jacob-carlborg/dvm/tree/master You could try reducing the bug using DustMite, and this helper: https://github.com/CyberShadow/DustMite/wiki/Suppressing-Windows-crashes
Re: Recursive lambda functions?
On Monday, 30 December 2013 at 21:15:43 UTC, Ilya Yaroshenko wrote: On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote: Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com This is not lambda =( I want something like enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function You can do this with __traits(parent, {}), but it's ugly. auto fact = function(int n) { if (n == 0) { return 1; } else { enum self = __traits(parent, {}); return n * self(n - 1); } }; Unfortunately, a shorter version written with the lambda syntax doesn't work, it just segfaults: auto fact = (int n) = (n 2) ? 1 : n * __traits(parent, {})(n - 1);
Re: A better way to write this function? (style question)
On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote: On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing? A few points: by declaring a new string and appending to it you are risking a lot of allocations. Either use std.array.appender or allocate the array with the correct size at the beginning. using .array on the end of the ufcs chain is yet another allocation. It can be avoided using std.algorithm.copy to copy the result back in to 'line' In my opinion the whole API would be better as range-based: auto splitSentence(R)(R input) if(isInputRange!R) { return input .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : c.toLower) .splitter!(' ') .filter!(a = !(a.empty)); } sorry, ignore that attempt, it's woefully broken...
Re: A better way to write this function? (style question)
On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing? Not a huge improvement and it could be a lot faster, no doubt: string[] split_sentence(string input) { import std.regex; auto split_re = ctRegex!(r[\n\r ]); return input.split(split_re) .map!toLower .filter!(a = !a.empty) .array(); } You could return the result of filter instead of an array to make it lazy and avoid an allocation if the caller is able to use it in that form. toLower had some really slow and incorrect behavior but I think that was fixed in 2.064. It still might be ASCII only though. I believe std.uni has a toLower that is correct for all of unicode.
Re: A better way to write this function? (style question)
On Monday, 30 December 2013 at 22:30:02 UTC, John Colvin wrote: On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote: On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing? A few points: by declaring a new string and appending to it you are risking a lot of allocations. Either use std.array.appender or allocate the array with the correct size at the beginning. using .array on the end of the ufcs chain is yet another allocation. It can be avoided using std.algorithm.copy to copy the result back in to 'line' In my opinion the whole API would be better as range-based: auto splitSentence(R)(R input) if(isInputRange!R) { return input .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : c.toLower) .splitter!(' ') .filter!(a = !(a.empty)); } sorry, ignore that attempt, it's woefully broken... Re: weird literal syntax, you didn't happen to be using dpaste to test and have trouble with character literals, did you? Because I did and thought I was going insane until realized DPaste was broken.
Re: A better way to write this function? (style question)
On Monday, 30 December 2013 at 22:38:43 UTC, Brad Anderson wrote: On Monday, 30 December 2013 at 22:30:02 UTC, John Colvin wrote: On Monday, 30 December 2013 at 22:17:21 UTC, John Colvin wrote: On Monday, 30 December 2013 at 21:40:58 UTC, Thomas Gann wrote: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Here is the function is question: string[] split_sentence(string input) { string line; foreach(c; input) { if(c == '\n' || c == '\r') line ~= ' '; else line ~= c.toLower(); } return line.splitter(' ').filter!(a = a.length).array; } Obviously, one issue is that because the string is immutable, I can't modify it directly, and so I actually build an entirely new string in place. I would have just made a mutable duplicate of the input and modify that, but then I would get errors returning, because it expects string[] and not char[][]. Is there a more elegant way to do what I'm doing? A few points: by declaring a new string and appending to it you are risking a lot of allocations. Either use std.array.appender or allocate the array with the correct size at the beginning. using .array on the end of the ufcs chain is yet another allocation. It can be avoided using std.algorithm.copy to copy the result back in to 'line' In my opinion the whole API would be better as range-based: auto splitSentence(R)(R input) if(isInputRange!R) { return input .map!(c = (c == \n[0] || c == \r[0]) ? ' ' : c.toLower) .splitter!(' ') .filter!(a = !(a.empty)); } sorry, ignore that attempt, it's woefully broken... Re: weird literal syntax, you didn't happen to be using dpaste to test and have trouble with character literals, did you? Because I did and thought I was going insane until realized DPaste was broken. oohhh so that was what that was. Anyway, here's what I have so far: import std.range : isInputRange; auto splitSentence(R)(R input) if(isInputRange!R) { import std.algorithm : map, splitter, filter; import std.uni : toLower; import std.range : ElementType; dchar preProc(ElementType!R c) { return (c == '\n' || c == '\r') ? ' ' : c.toLower; } return input .map!preProc .splitter!(c = c == ' ') .filter!(a = !(a.empty)); } I have to have the function instead of a lamda in order to get the return type correct. I guess I could cast or use std.conv.to instead. Anyway, the big problem I've hit is that AFAICT std.algorithm makes a complete mess of unicode and i can't find a byCodeUnit range anywhere in order to make it correct.
Re: Recursive lambda functions?
On Monday, 30 December 2013 at 21:58:29 UTC, Timon Gehr wrote: On 12/30/2013 10:15 PM, Ilya Yaroshenko wrote: On Monday, 30 December 2013 at 12:24:28 UTC, lomereiter wrote: Use Y combinator? http://forum.dlang.org/thread/mailman.157.1385247528.2552.digitalmars-d-le...@puremagic.com#post-l6rgfq:24g5o:241:40digitalmars.com This is not lambda =( I want something like enum factrorial5 = (a = a == 0 ? 1 : a * __lambda(a-1))(5); //Recursive pure lambda function enum factorial5=(function int(a)=a==0?1:a*__traits(parent,{})(a-1))(5); (In D, you need to specify the return type for a recursive function declaration. If one doesn't here, DMD crashes, which is a bug. https://d.puremagic.com/issues/show_bug.cgi?id=11848) And of course I'm wrong about that as soon as I post. No idea why one works when the other doesn't...
Re: A better way to write this function? (style question)
Thomas Gann: I've written a Markov bot in D, and I have function whose job it is to take an input string, convert all newline characters to spaces and all uppercase letters to lowercase, and then return an array of words that are generated by splitting the string up by whitespace. Take a look at the ways I have used here: http://forum.dlang.org/thread/zdhfpftodxnvbpwvk...@forum.dlang.org Bye, bearophile
Re: Recursive lambda functions?
On 12/30/2013 11:50 PM, Meta wrote: enum factorial5=(function int(a)=a==0?1:a*__traits(parent,{})(a-1))(5); (In D, you need to specify the return type for a recursive function declaration. If one doesn't here, DMD crashes, which is a bug. https://d.puremagic.com/issues/show_bug.cgi?id=11848) And of course I'm wrong about that as soon as I post. No idea why one works when the other doesn't... AFAICT, none of the cases is supposed to work: https://d.puremagic.com/issues/show_bug.cgi?id=8307 Presumably it is the same bug that causes the segfault. The underlying cause might be a missing check for completion of return type inference. In the first case, this means that the return type of the function is null when it is encountered in the function body. When null is checked for compatibility with multiplication with an int, a null pointer dereference occurs. In the second case, the return type has been partly resolved to 'int' as the first return statement has been analyzed to completion before the function call is encountered.
Re: Debug/reduce stack overflow in DMD on Windows
On 2013-12-30 23:21, Vladimir Panteleev wrote: You could try reducing the bug using DustMite, and this helper: Thanks, DustMite was able to find a reduced test case. It was this little piece of code: enum : DWORD { DWORD = REG_DWORD } -- /Jacob Carlborg
Re: Possible bug - should the following code cause an access violation exception?
Thanks Ali. I uninstalled 2.63.x. Installed the 2.64.2. I compiled and ran the test, and surely enough there were no problems. However, when I build using Visual D environment, the problem persists. Microsoft Visual Studio 2010 Ultimate. Visual D plugin. Thankfully, there is a simple workaround, but hopefully someone can get to the bottom of this issue.
Re: Possible bug - should the following code cause an access violation exception?
On 12/30/2013 04:55 PM, Afshin wrote: Thanks Ali. I uninstalled 2.63.x. Installed the 2.64.2. I compiled and ran the test, and surely enough there were no problems. However, when I build using Visual D environment, the problem persists. Microsoft Visual Studio 2010 Ultimate. Visual D plugin. Thankfully, there is a simple workaround, but hopefully someone can get to the bottom of this issue. Not unless somebody files a bug report. ;) https://d.puremagic.com/issues/ Ali
Re: A better way to write this function? (style question)
Thanks for all your replies, guys! I have done some further research in the meantime and I have found out that I am, in fact, an idiot. There is actually a standard library function that does exactly what I am trying to do! As it turns out, std.string.split(): 1) It automatically discards empty tokens, so there is no need to filter it manually. 2) Its definition of whitespace includes spaces, tabs, and both types of newlines, so there is no need to convert newlines to spaces. An equivalent, but much less verbose, form of the function becomes the following: input.toLower.split; So I'm noticing a common theme here, though, which is that lots of operations on arrays is bad? Should I be using ranges pretty much everywhere, then? Or just in performance-critical areas of code where I want to avoid a lot of copying? Would that just leave plain vanilla dynamic arrays to the task of (relatively) permanent storage?
How to organize using modules?
Is it possible to describe modules in terms of packages (as found in Java)? The features that Java packages have that I can't seem to get in D are: 1) You can have classes that are in the same package, but kept in separate files. 2) You can import many classes using the '*' syntax. Is this possible in D? What I understand is that if I have ClassA and ClassB in Module1, and I want to keep the classes in separate files, then I have to use the following module statements: in ClassA: module Module1.ClassA; in ClassB: module Module1.ClassB; But now it becomes cumbersome to use the classes because now I have to import them explicitely: import Module1.ClassA; import Module1.ClassB; If I wanted to use: import Module1; Then it seems I have to have ClassA and ClassB in the same D file. Am I missing something?
Re: How to organize using modules?
On Tuesday, 31 December 2013 at 06:01:21 UTC, Afshin wrote: Is it possible to describe modules in terms of packages (as found in Java)? The features that Java packages have that I can't seem to get in D are: 1) You can have classes that are in the same package, but kept in separate files. 2) You can import many classes using the '*' syntax. Is this possible in D? What I understand is that if I have ClassA and ClassB in Module1, and I want to keep the classes in separate files, then I have to use the following module statements: in ClassA: module Module1.ClassA; in ClassB: module Module1.ClassB; But now it becomes cumbersome to use the classes because now I have to import them explicitely: import Module1.ClassA; import Module1.ClassB; If I wanted to use: import Module1; Then it seems I have to have ClassA and ClassB in the same D file. Am I missing something? It is possible if you have your file system set up like this. Module1 -ClassA.d -ClassB.d -package.d //In Module1/ClassA.d module Module1.ClassA; class ClassA { ... } //In Module1/ClassB.d module Module1.ClassB; class ClassB { ... } //In Module1/package.d module Module1; public import Module1.ClassA; public import Module1.ClassB; //In main.d module main; import Module1; //This will import both ClassA and ClassB. Very important! The name of the file with the public imports must be package.d
Re: How to organize using modules?
2) You can import many classes using the '*' syntax. You don't use the * syntax. Just stop after the module name.