Re: What the hell is wrong with D?
On Saturday, 23 September 2017 at 20:43:36 UTC, Patrick Schluter wrote: So I checked for all the languages listed: C, C#, Java, Javascript, C++, PHP, Perl and D. All have the same order of precedence except, as always the abomination of all languages: C++ (kill it with fire). C++ is the only language that has the ternary operator have the same precedence than the assignment operators. This means a>=5?b=100:b=200; will compile in C++ but not in all the other languages. That's one reason why it irritates me when people continuously refer to C and C++ as if it was the same thing (yes I mean you Walter and Andrei). Even PHP and Perl got it right, isn't that testament of poor taste Bjarne?. :-) It's not quite as big of a deal as it seems because of the RTL associativity for both of them but still a very weird thing at face value.
Re: What the hell is wrong with D?
On Tuesday, 19 September 2017 at 19:16:05 UTC, EntangledQuanta wrote: [snip] I'm just glad there is at least one sane person that decided to chime in... was quite surprised actually. I find it quite pathetic when someone tries to justify a wrong by pointing to other wrongs. It takes away all credibility that they have. I have no doubt that had someone thought to propose addressing this when the language was new it would have been seriously considered and likely accepted (given how frequently this causes bugs). D tried to fix a lot of behavior from C that was bug prone but it didn't catch everything. If you want to help, I suggest trying to come up with a DIP that addresses it while being conscious of how to avoid breaking an enormous amount of code. I suspect it's a hard and maybe impossible problem but if you are up for the challenge I'm sure your efforts would be welcome.
Re: What the hell is wrong with D?
On Tuesday, 19 September 2017 at 18:17:47 UTC, jmh530 wrote: On Tuesday, 19 September 2017 at 17:40:20 UTC, EntangledQuanta wrote: Thanks for wasting some of my life... Just curious about who will justify the behavior and what excuses they will give. Pretty sure it would be exactly the same thing in C... It is (and Java and C# and pretty much every other C style language though the nicer implicit conversion rules means it gets caught more easily). It is a big source of programmer mistakes. It comes up frequently in PVS Studio's open source analysis write ups.
Re: Ranges suck!
On Thursday, 14 September 2017 at 23:53:20 UTC, Your name wrote: Every time I go to use something like strip it bitches and gives me errors. Why can't I simply do somestring.strip("\n")??? import std.string would be the likely strip yet it takes a range and somestring, for some retarded reason, isn't a range. strip isn't the only function that does this. Who ever implemented ranges the way they did needs to get their head checked! It's not really a range issue. It's that there are two strips. One in std.string and one in std.algorithm. The latter which lets you define what to strip rather than just whitespace is what you are looking for and works as you've written. The former is there for legacy reasons and we can hopefully get rid of it in the future to avoid this confusion. I'd also say that you don't seem to be grasping a pretty fundamental D concept yet. std.string.strip doesn't take two arguments, it takes one argument. The first set of parentheses is the template argument which is inferred from the regular argument using IFTI. [snip] Ok, so I know what your saying "Oh, but strip("\n") should be strip()! Your a moron RTFM!" But why then force me to strip for nothing? Why not pay me? e.g., let me strip for something like strip("x")? strip()! isn't valid syntax. If you want to strip all whitespace you can use std.string.strip (e.g., somestring.strip()). If you want to strip "x" you can use std.algorithm.strip (e.g., somestring.strip("x")). Pretty much like any other language minus the double function mess. Oh, chomp? Is that the function I'm suppose to use? Seriously? Was the D lib written by someone with a pacman fetish? chomp comes to D by way of perl. I don't know whether or not Larry Wall is into pacman or not.
Re: Chain a range of ranges?
On Tuesday, 17 January 2017 at 03:21:39 UTC, Yuxuan Shui wrote: The built in chain seems to only be able to chain a fixed number of ranges, is there a way to chain a range/array of ranges? See std.algorithm.iteration.joiner
Re: D code optimization
On Thursday, 22 September 2016 at 16:09:49 UTC, Sandu wrote: It is often being claimed that D is at least as fast as C++. Now, I am fairly new to D. But, here is an example where I want to see how can this be made possible. So far my C++ code compiles in ~850 ms. While my D code runs in about 2.1 seconds. [snip] Just a small tip that applies to both D and C++ in that code. You can use a static array rather than a dynamically allocated array in the loop (enum n = 252; then double[n+1] call; in D). You can also use "double[n+1] call = void;" to mimic C++'s behavior of uninitialized memory. Use GDC or LDC when doing performance related work as they generate faster code typically. I'd be surprised if the C++ and D code asm wasn't nearly identical for a big chunk of this code when using GCC/GDC or Clang/LDC.
Re: Can vibe d leverage existing web technologies?
On Tuesday, 13 September 2016 at 23:45:18 UTC, Intersteller wrote: vibe.d does not have much lateral support as the most commons web technologies do. Can vibe.d leverage pre-existing techs such as php, ruby/rails, etc? Starting from scratch and having to build a robust and secure framework is really not the way to go. Sure. Just use res.write(executeShell(["php", "-f", "somephpscript.php"]).output); or something like that. But seriously, you probably don't want to do that. It's like asking if ruby on rails can leverage php. Sure, they can communicate over HTTP or whatever else they support but trying to execute PHP from within Rails or vice versa just isn't really all that beneficial.
Re: dlang.org using apache?
On Wednesday, 8 June 2016 at 14:41:55 UTC, Ola Fosheim Grøstad wrote: [snip] I like the "are we fast yet" websites that various project put up, displaying improvements over time. You mean like this? http://digger.k3.1azy.net/trend/
Re: iota access in foreach loop
On Saturday, 4 June 2016 at 18:55:09 UTC, Brad Anderson wrote: On Saturday, 4 June 2016 at 18:20:26 UTC, Alex wrote: [...] Check out enumerate() in std.range; int counter = 5; foreach(i, el; enumerate(randomCover(iota(counter writeln("index: ", i, " element: ", el); index: 0 element: 3 index: 1 element: 1 index: 2 element: 0 index: 3 element: 2 index: 4 element: 4 How could I have forgotten the UFCS rox version... foreach(i, el; iota(counter).randomCover.enumerate)
Re: iota access in foreach loop
On Saturday, 4 June 2016 at 18:20:26 UTC, Alex wrote: Hi all! Could you help me clearify why a iota can't be accessed with two arguments in a foreach loop? following tests show my problem: What does work: int[] ku = [0, 1, 2, 3, 4]; foreach(i, el; ku) writeln("index: ", i, " element: ", el); What does not work: counter = 5; foreach(i, el; iota(counter)) writeln("index: ", i, " element: ", el); Motivation: In real I want to have: counter = 5; foreach(i, el; randomCover(iota(counter))) writeln("index: ", i, " element: ", el); so, I could follow a random permutation. Maybe there is another simple way to achieve this? PS: needed imports: import std.random : randomCover; import std.range : iota; import std.stdio : writeln; Check out enumerate() in std.range; int counter = 5; foreach(i, el; enumerate(randomCover(iota(counter writeln("index: ", i, " element: ", el); index: 0 element: 3 index: 1 element: 1 index: 2 element: 0 index: 3 element: 2 index: 4 element: 4
Re: Speed of csvReader
On Thursday, 21 January 2016 at 22:13:38 UTC, Brad Anderson wrote: On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: [...] What about wrapping the slices in a range-like interface that would unescape the quotes on demand? You could even set a flag on it during the initial pass to say the field has double quotes that need to be escaped so it doesn't need to take a per-pop performance hit checking for double quotes (that's probably a pretty minor boost, if any, though). Oh, you discussed range-based later. I should have finished reading before replying.
Re: Speed of csvReader
On Thursday, 21 January 2016 at 21:24:49 UTC, H. S. Teoh wrote: [snip] There are some limitations to this approach: while the current code does try to unwrap quoted values in the CSV, it does not correctly parse escaped double quotes ("") in the fields. This is because to process those values correctly we'd have to copy the field data into a new string and construct its interpreted value, which is slow. So I leave it as an exercise for the reader to implement (it's not hard, when the double double-quote sequence is detected, allocate a new string with the interpreted data instead of slicing the original data. Either that, or just unescape the quotes in the application code itself). What about wrapping the slices in a range-like interface that would unescape the quotes on demand? You could even set a flag on it during the initial pass to say the field has double quotes that need to be escaped so it doesn't need to take a per-pop performance hit checking for double quotes (that's probably a pretty minor boost, if any, though).
Re: Disabling GC in D
On Thursday, 21 January 2016 at 21:54:36 UTC, Dibyendu Majumdar wrote: Is there a way to disable GC in D? I am aware of the @nogc qualifier but I would like to completely disable GC for the whole app/library. Regards Dibyendu GC.disable(); This prevents the garbage collector from running but your program will still allocate using the GC's managed memory (use the command line switch -vgc to see all the allocation points). It will just never free memory.
Re: DUB config format: SDLang or JSON?
On Friday, 18 December 2015 at 22:30:00 UTC, Jakob Jenkov wrote: I am just looking at DUB and I can read that there are two config formats: SDLang and JSON. Which one is the "new" format? Which one is the "future" of DUB? SDLang is the new one. JSON will remain supported. Use whichever you like better.
Re: Palindromes
On Friday, 4 December 2015 at 00:50:17 UTC, Meta wrote: On Friday, 4 December 2015 at 00:26:23 UTC, Jim Barnett wrote: On Friday, 4 December 2015 at 00:23:45 UTC, Jim Barnett wrote: The `import` statement inside the `for`-loop kind of smells to me. Sorry, inside the `while` loop In D it's considered idiomatic, but it can also cause some very hard to detect errors from time to time... I hate it for this reason and never do it in my own code. Inside a while, I don't think, really matches the idiom's goals. By only sticking imports inside the code that makes use of them you can achieve (I've never measured it though) compilation performance improvements in code that then imports the containing module but never makes use of the code in question. Sticking the import in the middle of the code is just noisy though, you want it nearby with limited scope but otherwise out of the way.
Re: Password Storage
On Friday, 27 November 2015 at 00:17:34 UTC, brian wrote: [snip] Can the developers in the room confirm if this is the correct approach? Are there examples of betters ways of doing this? Regards Brian Botan has well thought out password hashing: https://github.com/etcimon/botan/wiki/Password-Hashing
Re: compatible types for chains of different lengths
On Tuesday, 17 November 2015 at 22:47:17 UTC, Jon D wrote: I'd like to chain several ranges and operate on them. However, if the chains are different lengths, the data type is different. This makes it hard to use in a general way. There is likely an alternate way to do this that I'm missing. [snip] Is there a different way to do this? --Jon One solution: import std.stdio; import std.range; import std.algorithm; void main(string[] args) { auto x1 = ["abc", "def", "ghi"]; auto x2 = ["jkl", "mno", "pqr"]; auto x3 = ["stu", "vwx", "yz"]; auto chain1 = chain(x1, (args.length > 1) ? x2 : []); auto chain2 = chain(x1, x2, (args.length > 1) ? x3 : []); chain1.joiner(", ").writeln; chain2.joiner(", ").writeln; }
Re: How to install DMD 64bit on Windows?
On Wednesday, 21 October 2015 at 18:50:08 UTC, Adam D. Ruppe wrote: Use the .exe installer and it will offer to download and install visual studio for you as part for its process. I don't know if that feature has made it into a release yet. I don't think Vc2015 is supported yet either in a released version of DMD. I could be mistaken on both of these. If you want to play it say just install VS2013 Community Edition then install DMD and everything should just work.
Re: 'strong types' a la boost
On Saturday, 14 March 2015 at 15:45:30 UTC, Charles Cooper wrote: I think I may have answered my own question. It seems std.typecon provides a facility for this. http://dlang.org/phobos/std_typecons.html#.Proxy http://dlang.org/phobos/std_typecons.html#.Typedef Is this the 'right' way to do things? It seems that Proxy is used as a mixin whereas Typedef is used to create standalone types. If memory serves me, Typedef was created to regain this exact feature after "typedef" was deprecated. "typedef" did this while its replacement, "alias", did not and the realization that we had lost that capability led to the creation of Typedef.
Re: Beginner ?. Why does D suggest to learn java
On Thursday, 16 October 2014 at 22:26:51 UTC, RBfromME wrote: I'm a newbie to programming and have been looking into the D lang as a general purposing language to learn, yet the D overview indicates that java would be a better language to learn for your first programming language. Why? Looks like D is easier than Java... The Overview page is ancient and needs to be rewritten. The included example sieve program reflects this. It's almost C (you'd only need to make minor changes to 4 of the lines to make it build with gcc). I'd agree that C probably isn't a good first language. The overview also suggests learning BASIC first which also shows just how old the Overview is (where do you even get a BASIC compiler these days?). There are easier languages but modern, idiomatic D is perfectly approachable for beginners in my opinion. https://issues.dlang.org/show_bug.cgi?id=13624
Re: how to get the \uxxxx unicode code from a char
On Tuesday, 14 October 2014 at 20:08:03 UTC, Brad Anderson wrote: On Tuesday, 14 October 2014 at 20:05:07 UTC, Brad Anderson wrote: https://github.com/D-Programming-Language/phobos/blob/master/std/json.d#L579 Oops. Linked the the parser section. I actually don't see any unicode escape encoder in here. Perhaps he meant the upcoming JSON module. Here we go. https://github.com/s-ludwig/std_data_json/blob/4ecb90626055269f4897902404741f1173fb5e8e/source/stdx/data/json/generator.d#L451 Sönke's is pretty sophisticated. You could probably just use the non-surrogate supporting simple branch.
Re: how to get the \uxxxx unicode code from a char
On Tuesday, 14 October 2014 at 20:05:07 UTC, Brad Anderson wrote: https://github.com/D-Programming-Language/phobos/blob/master/std/json.d#L579 Oops. Linked the the parser section. I actually don't see any unicode escape encoder in here. Perhaps he meant the upcoming JSON module.
Re: how to get the \uxxxx unicode code from a char
On Tuesday, 14 October 2014 at 20:03:37 UTC, jicman wrote: On Tuesday, 14 October 2014 at 19:49:16 UTC, Sean Kelly wrote: On Tuesday, 14 October 2014 at 19:47:00 UTC, jicman wrote: Greetings. Imagine this code, char[] s = "ABCabc"; foreach (char c; s) { // how do I convert c to something an Unicode code? ie. \u. } I'd look at the JSON string encoder. JSON? What does JSON has to do with my basic D? :-) No thanks. :-) Sean's saying that the JSON encoder does the same thing so you can look there for how to do it. https://github.com/D-Programming-Language/phobos/blob/master/std/json.d#L579
Re: Turn function into infinite range
On Monday, 29 September 2014 at 17:02:43 UTC, Martin Nowak wrote: Does anyone know a construct to turn a lambda into an infinite range. import std.random; unittest { Random gen; foreach(v; xxx!(() => uniform(0, 100, gen)).take(10)) writeln(v); } I though I've seen this around somewhere but can no longer find it. I can't find anything to do it. That seems weirdly absent. You can abuse recurrence to do it. Random gen; foreach(v; recurrence!((a, n) => uniform(0, 100, gen))(0).dropOne.take(10)) writeln(v);
Re: Using the delete Keyword /w GC
On Monday, 25 August 2014 at 17:10:11 UTC, Etienne wrote: People have been saying for quite a long time not to use the `delete` keyword on GC-allocated pointers. I've looked extensively through the code inside the engine and even made a few modifications on it/benchmarked it for weeks and I still can't see why it would be wrong. Wouldn't it help avoid collections and make a good hybrid of manual management/collected code? The free lists in the GC engine look quite convenient to use. Any ideas? delete was deprecated because it is memory unsafe (there may still be references to the memory). You can still use GC.free() to free the memory but it must only be used with care. I feel if you are managing delete yourself you might as well manage allocation yourself too and take pressure off the GC. If you are sure you have only one reference and GC.free() is safe, Unique was probably a better choice anyway.
Re: new error message in 2.066, type bool (const)
On Thursday, 21 August 2014 at 03:02:53 UTC, Paul D Anderson wrote: What changed? It ran okay with early beta versions, but not with the release. Paul It compiles in beta-5 but not beta-6. Is the list of changes in the beta testing wiki complete? None seem pertinent. monarch_dodra: Thanks for checking. I was trying to avoid tearing everything down. I was hoping someone would recognize the error. Looks like I'll have to chase it down. Paul https://github.com/CyberShadow/digger should be able to help find the exact commit. A reduced example would help us figure out what is going on though.
Re: Produce some COFF object with 2.066 ?
On Wednesday, 20 August 2014 at 23:56:23 UTC, Baz wrote: Hello, I've been very interested about the announce saying that DMD is able to produce COFF object files. Mostly because I'm thinking using some objects programmed in D in a software programmed in another lang, a bit like when statically linking a dll to a program but with an obj, to keep a nice monolithic executable. First thing: I've tried a simple thing: compile an exported function with the args "myfile.d -c -ms32mscoff" and dmd complains that "-ms32mscoff" is not a recognized switch. 32-bit COFF is only in git master currently. It'll be in 2.067 when that comes out. 64-bit COFF has been in dmd for quite some time now. You just have to have a copy of Visual Studio installed (the free Express edition should be fine) and compile with -m64. Second thing: If I understand well, it means that previously, to link D a object with a soft programmed in another lang was not possible because the OMF objs don't include everything (e.g the objs coming from other imported static libs) and that now it's faisable ? right ? They'd just have to both be OMF format if you wanted to statically link. If you had a DLL you could create an import library from the DLL and still link that just fine. Walter has a tool on Digital Mars to do it. Now you should be able to directly link to COFF libraries.
Re: Appender is ... slow
On Thursday, 14 August 2014 at 19:10:18 UTC, Jonathan M Davis wrote: I've never really tried to benchmark it, but it was my understanding that the idea behind Appender was to use it to create the array when you do that via a lot of appending, and then you use it as a normal array and stop using Appender. It sounds like you're trying to use it as a way to manage reusing the array, and I have no idea how it works for that. But then again, I've never actually benchmarked it for just creating arrays via appending. I'd just assumed that it was faster than just using ~=, because that's what it's supposedly for. But maybe I just completely misunderstood what the point of Appender was. - Jonathan M Davis I too have trouble understanding what Appender does that supposedly makes it faster (at least from the documentation). My old, naive thought was that it was something like a linked list of fixed size arrays so that appends didn't have to move existing elements until you were done appending, at which point it would bake it into a regular dynamic array moving each element only once looking at the code it appeared to be nothing like that (an std::deque with a copy into a vector in c++ terms). Skimming the code it appears to be more focused on the much more basic "~= always reallocates" performance problem. It seems it boils down to doing essentially this (someone feel free to correct me) in the form of an output range: auto a = /* some array */; auto b = a; a = a.array(); for(...) b.assumeSafeAppend() ~= /* element */; (assumeSafeAppend's documentation doesn't say whether or not it'll reallocate when capacity is exhausted, I assume it does).
Re: core.thread.Fiber --- runtime stack overflow unlike goroutines
On Thursday, 14 August 2014 at 07:46:29 UTC, Carl Sturtivant wrote: The default size of the runtime stack for a Fiber is 4*PAGESIZE which is very small, and a quick test shows that a Fiber suffers a stack overflow that doesn't lead to a clean termination when this limit is exceeded. This makes it difficult to simulate deterministic alternation where the stack size needed is unpredictable because complex deterministic computations are going on inside Fibers. In contrast, the Go programming language's goroutines can extend their stacks as needed at runtime, and so can be used to simulate deterministic alternation without this limitation, and yet be initially executed with each having only a small stack size. There seems to be a claim that all that's needed to add D-routines (goroutines for D) is a scheduler and a Channel type, on top of Fiber. http://forum.dlang.org/thread/lphnen$1ml7$1...@digitalmars.com See the initial post, point 7., as well as supporting remarks in later replies. Am I missing something? Is there a clean and simple way to get Fiber to no longer suffer a stack overflow when implementing D-routines? Segmented stacks come with a cost. Rust abandoned them for reasons you can read about here: https://mail.mozilla.org/pipermail/rust-dev/2013-November/006314.html I believe Go has taken steps to help mitigate stack thrashing but I don't know if they have been successful yet.
Re: Need help with building dmd
On Thursday, 7 August 2014 at 01:50:50 UTC, Phil Lavoie wrote: On Thursday, 7 August 2014 at 01:37:46 UTC, Brad Anderson wrote: On Thursday, 7 August 2014 at 01:27:55 UTC, Phil Lavoie wrote: Nope, still not working, but thx. Hmm, are you in the src directory? Yes and ls *.mak shows three makefiles: osmodel.mak posix.mak win32.mak ls? If you're not, I recommend using the cmd.exe terminal. optlink has had problems with using other terminals. You may want to look at this guide if you haven't already: http://wiki.dlang.org/Building_DMD
Re: Need help with building dmd
On Thursday, 7 August 2014 at 01:27:55 UTC, Phil Lavoie wrote: Nope, still not working, but thx. Hmm, are you in the src directory?
Re: Need help with building dmd
On Thursday, 7 August 2014 at 01:15:36 UTC, Phil Lavoie wrote: [...] make release -fwin32 Here is the output: Error: can't read makefile 'win32' I'm building on Windows btw. Thanks, Phil Close. You need the extension, I believe. make -f win32.mak release
Re: Taking from infinite forward ranges
On Tuesday, 5 August 2014 at 01:23:19 UTC, Andrew Edwards wrote: Is there a way to take a bounded rage from a infinite forward range? Given the Fibonacci sequence: auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1); I can take the first n elements: take(fib, 10); But say I want all positive elements below 5 in value (there are eight such values [2, 8, 34, 144, 610, 2584, 10946, 46368]), how would I "take" them? Of course I could filter the range, leaving only positive values, and then take(fib, 8). But what if I didn't know there were 8, how could I take them from there filtered range? Currently I do this: foreach(e; fib) { if (e >= val) break; // so something with e } or while((e = fib.front()) < n) { // do something with e fib.popFront(); } Is there a better way? I'd use std.algorithm.until: void main() { import std.algorithm, std.range, std.stdio; auto fib_until_50k = recurrence!("a[n-1] + a[n-2]")(1, 1) .until!(a => a > 50_000); writeln(fib_until_50k); }
Re: Create a general array
On Thursday, 24 July 2014 at 19:43:23 UTC, Robert Rimoczi wrote: Hi! Can I somehow make a general array where I can store everykind of object? doubles, ints, float, class objects? Or is there any method for it? void main() { import std.variant, std.stdio; class Four { override string toString() const { return "4"; } } Variant[] anything; anything ~= Variant(1.0); anything ~= Variant(2); anything ~= Variant(3.0f); anything ~= Variant(new Four()); writeln(anything); } You'll want to read up on std.variant.Variant to understand how to use it. Look at get() in particular but there are other methods that you may need depending on how you are using it.
Re: Problem with trying sample from doc page
On Wednesday, 16 July 2014 at 15:44:03 UTC, Adam D. Ruppe wrote: I would just change all the longs to ints and it would probably work. Or all the longs to ints. It really should have been consistent in the docs, since the point of this is delegate vs function, not int vs long... https://github.com/D-Programming-Language/dlang.org/pull/615
Re: Regex match in for loop
On Tuesday, 15 July 2014 at 20:18:58 UTC, seany wrote: Consider this: import std.stdio, std.regex, std.array, std.algorithms ; void main(string args[]) { string[] greetings = ["hello", "hallo", "hoi", "salut"]; regex r = regex("hello", "g"); for(short i = 0; i < greetings.count(); i++) { auto m = match(greetings[i], r); } } To the best of my knowledge, declaring a variable inside a for loop is illegal, you can not delacre the same variable repeatedly over the iterations. There is nothing wrong with declaring a variable in a for loop. It's just limited to the scope inside the for loop so it's not useful if you need the variable after the for loop ends. Also just the declaration auto m; outside the for loop does not make sense either - auto needs an Right Hand Side expression. So what is the correct way of doing it? You can type out the return type. It can be a little tricky to determine sometimes though so you can also use typeof() like: typeof(match(greetings[i], r) m; to get the proper type. You should use matchFirst and matchAll instead of match and the "g" flag. It's more clear and easier to use. What are you trying to do in this bit of code? There may be a better overall structure.
Re: Generating Strings with Random Contents
On Monday, 14 July 2014 at 22:32:25 UTC, bearophile wrote: Brad Anderson: Alternative: randomSample(lowercase, 10, lowercase.length).writeln; From randomSample docs: Selects a random subsample out of r, containing exactly n elements. The order of elements is the same as in the original range.< Bye, bearophile Hmm, good catch. Not the behavior I expected.
Re: Generating Strings with Random Contents
On Monday, 14 July 2014 at 22:27:57 UTC, Brad Anderson wrote: Alternative: randomSample(lowercase, 10, lowercase.length).writeln; std.ascii should really be using std.encoding.AsciiString. Then that length wouldn't be necessary.
Re: Generating Strings with Random Contents
On Monday, 14 July 2014 at 22:21:36 UTC, bearophile wrote: Nordlöw: Is there a natural way of generating/filling a string/wstring/dstring of a specific length with random contents? Do you mean something like this? import std.stdio, std.random, std.ascii, std.range, std.conv; string genRandomString(in size_t len) { return len .iota .map!(_ => lowercase[uniform(0, $)]) .text; } void main() { import std.stdio; 10.genRandomString.writeln; } Bye, bearophile Alternative: randomSample(lowercase, 10, lowercase.length).writeln;
Re: '!' and naming conventions
On Wednesday, 18 June 2014 at 21:58:48 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: Sent: Wednesday, June 18, 2014 at 11:02 PM From: "Brad Anderson via Digitalmars-d-learn" To: digitalmars-d-learn@puremagic.com Subject: Re: '!' and naming conventions There is a style guide on the website: http://dlang.org/dstyle.html Personally I just consider this a Phobos contributor style guide and not like a PEP8 style guideline. It was written with the hope that it would be generally followed by the D community, and that's part of the reason that it specifically focuses on the API and not the formatting of the code itself. So, ideally, most D projects would follow it (particularly if they're being distributed publicly) so that we have consistency across the community (particularly with regards to how things are captitalized and whatnot), but by no means is it required that every D project follow it. It's up to every developer to choose how they want to go about writing their APIs. We're not fascists and don't require that all code out there be formatted in a specific way or that all APIs follow exact naming rules (we couldn't enforce that anyway). But still, I would hope that most public D librares would follow the naming guidelines in the D style guide. Now, for Phobos, it's required, and there are even a couple of formatting rules added to the end specifically for Phobos, but outside of official D projects, it's up to the developers of those projects to choose what they want to do. - Jonathan M Davis I think it's a pretty good basic style guide overall and I follow it quite a bit, mostly due to coincidence (it overlaps with my own style I've developed over the years quite a bit). Really, the main thing I do differently is I use all lowercase, underscored names for variables instead of camelcasing. I don't care for the look of camelcase so I only use it for globals and other infrequently used things where I want it to stand out a bit from my regular variables. What we really need is a D Idiom Guide but that's a much more difficult and controversial subject.
Re: '!' and naming conventions
On Wednesday, 18 June 2014 at 20:55:36 UTC, cym13 wrote: Hello, I see a lot of functions and other stuff with a '!' in the name such as 'bitfields!' or 'ctRegex!'. What does it mean exactly? In scheme, we use such a convention to warn that a function is not pure, but I don't see the point of using it that way in D as there are other way to express it. Moreover, I'm looking for a style guide of D, something like the PEP8 for python. Is there anything like that? Thanks! The ! specifies that a template argument list follows. auto fun(T)(T a, T b) { return a * b; } void main() { // fun can be called using several different ways: fun!(int)(1, 2); // Specifying the template arguments fun!int(1, 2); // If there is only one template argument the // parens can be omitted fun(1, 2); // IFTI can be used to figure out the types for you } There is a style guide on the website: http://dlang.org/dstyle.html Personally I just consider this a Phobos contributor style guide and not like a PEP8 style guideline.
Re: Doing exercise from book, but I'm getting error with splitter
On Monday, 16 June 2014 at 16:38:15 UTC, Sanios wrote: And I'm getting this - Error: undefined identifier splitter It seems like std.string doesn't contain splitter. You can find the solution to this and other issues you may hit in the errata: http://erdani.com/tdpl/errata/
Re: zip with fieldTuple
On Friday, 6 June 2014 at 23:18:49 UTC, John wrote: On Friday, 6 June 2014 at 22:27:38 UTC, bearophile wrote: John: I can iterate over the struct elements with the traits FieldTypeTuple!foo, In such iteration you are using a static foreach. Types are compile-time constructs in D. If you need run-time entities you need to get their typeinfo. I don't want to do that lookup at runtime though. Clearly my intent is to rewrite this foreach zip expression as: auto s = test.split(","); writeln(to!int(s[0])); writeln(to!float(s[1])); What I wrote in my reply expands to exactly that. It's an array indexing which is very cheap (an addition on a ptr, basically). I can't think of a way to make this any faster if test is a runtime value. If test were a compile time value you could write it in such a way that it distills down to: writeln(1); writeln(2.0); But I suspect that's not what you are going for because test is meant to come in at runtime. zip only works on run time values. So you can't zip a built-in typetuple of types with a range of values. Conceptually that is what I want to do though. I want to pair the type with the string that I'm going to convert. I'm not sure if it's actually a range? I assumed it would be a range of some kind, It's not a range. FieldTypeTuple returns a built-in typetuple that in this case is really a built-in of types, that are purely compile-time entities. I get that. and each of the elements would have a supertype of something like 'type' since that's what they are. They are types (and they aren't other things like uninstantiated templates that in D are another kind), but not even in our dreams there is a supertype for them :-) It could infer that now you have two ranges, one of 'type' and one of 'string'. Nope. If I'm able to foreach over two things, shouldn't I be able to foreach over the paired ranges with zip? It seems so simple... If you turn the built-in typetuple of types into an array or lazy range of typeinfo, then you can zip them. But I don't think this is a good idea. It's better to forget the zipping and use a static foreach on the types, using also an index, and use such index to access the second array of run time values. I had already considered a workaround like that, but it's just that. A workaround. You already do unrolling for templates, this isn't much different (at least conceptually). You could basically do exactly what you're describing in the library, no? Have zip loop over all the static/compile time fields (assuming you can separate them in the template from the runtime ranges), and index into (or pop range) the runtime ranges with length checks. The compiler would unroll the compile time ranges (or whatever you want to call them) creating essentially exactly what you've described, the other poster mentioned, and precisely what I put above. Is that not possible? You could do something kind of like what you are describing, yes, but you have to remember that compile time values are passed in as template parameters. It'd have to look something like: zipWithTypes!(FieldTypeTuple!foo)(test.split(",")) And the element type of the result would have to be something like Variant if it's going to be a range. You could use a Tuple too if you don't care about the result having a range interface. Or you could represent types in runtime code with enums or something, like bearophile was saying.
Re: zip with fieldTuple
On Friday, 6 June 2014 at 22:16:36 UTC, John wrote: So let's say I'm trying to create a really simple ORM. I have a struct: struct foo { int a; float b; } I can iterate over the struct elements with the traits FieldTypeTuple!foo, I can iterate over the the string that represents the elements I want to shove in the struct, but when I try to loop over *both* of these at the same time with zip(...) I get an error. Code: void main() { string test = "1,2.0"; foreach (t, value; zip(FieldTypeTuple!foo, test.split(","))) { writeln(to!t(value)); } } Error: src\orm.d(13): Error: template std.range.zip does not match any function template declaration C:\D\dmd2\windows\bin\..\..\src\phobos\std\range.d(3808): Error: template std.range.zip cannot deduce template function from argument types !()((int, float),string[]) I get what the error message is saying, but I have no idea how to fix the code to do what I want. I tried to look up what the FieldTypeTuple actually returns but it's calling a method on the generic type T called tupleOf(), which I can't seem to find (in that file or as a general function on object). I'm not sure if it's actually a range? I assumed it would be a range of some kind, and each of the elements would have a supertype of something like 'type' since that's what they are. It could infer that now you have two ranges, one of 'type' and one of 'string'. If I'm able to foreach over two things, shouldn't I be able to foreach over the paired ranges with zip? It seems so simple... foreach-ing over a typetuple is very different from doing it over regular variables. The compiler basically expands the foreach into several blocks of code (without introducing scope, I believe). So you are mixing compile time values and runtime values in a weird way. Types can't be zipped up with runtime values (or zipped up at all without some extra work). One way to do what you want is to foreach over the typetuple and use the index to index into the runtime values like this: struct foo { int a; float b; } void main() { import std.range, std.traits, std.stdio, std.conv; string test = "1,2.0"; auto test_split = test.split(","); foreach (i, T; FieldTypeTuple!foo) { writeln(to!T(test_split[i])); } }
Re: how to get line number after readln
On Thursday, 5 June 2014 at 00:33:26 UTC, Ali Çehreli wrote: On 06/04/2014 05:05 PM, Robert Hathaway wrote: I've got a program that reads a text file line by line (using std.stdio readln()) Consider using byLine() instead. (Important: byLine uses an internal buffer for the line; so, don't forget to make a copy if you want to store the line for later use.) > and I'd like to refer to the line number when I send a message to stderr upon finding a mis-formatted line. Is there a way to get the current line number? Of course, I could create a counter and increment it with each call to readln, but is there a "cool" way of doing this? Okay, call me lazy... just don't call me late for dinner! :-) Robert One cool way is a zipped sequence: import std.stdio; import std.range; void main() { foreach (i, line; zip(sequence!"n", File("deneme.txt").byLine)) { writefln("%s: %s", i, line); } } Ali Once this[1] gets merged you'll be able to do this: foreach (lineNum, line; File("deneme.txt").byLine().enumerate(1)) writefln("%s: %s", lineNum, line); Which is a bit more clear about the intent. 1. https://github.com/D-Programming-Language/phobos/pull/1866
Re: DateTime custom string format
On Tuesday, 3 June 2014 at 18:22:59 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: Well, I would prefer to do it myself, but I obviously can't say that I wouldn't accept it if someone else did it and did a good job of it. The main problem however is that we need to come up with a good formatting scheme - that is the format of the custom time strings. What C has doesn't cut it, and what I proposed a while back turned out to be too complicated. Just for reference to Robert and others reading, here's Jonathan's old proposal: http://forum.dlang.org/post/mailman.1806.1324525352.24802.digitalmar...@puremagic.com
Re: How to get array length
On Thursday, 22 May 2014 at 23:22:44 UTC, kaz wrote: Is there a way to get the length of an array out of slice bracket in D? Tks. Just use .length: void main() { import std.stdio; auto a = new int[5]; auto b = a[]; writeln(a.length, " ", b.length); }
Re: Is there a standard way to parse hex strings into numbers?
On Monday, 24 March 2014 at 16:30:37 UTC, Gary Willoughby wrote: Is there a standard way to parse hex strings into numbers? I have the following returned as a string: 0xac036f90 Is there a standard way to parse this into a ulong or do you just roll your own? To accepts a radix parameter. You need to strip off the 0x though. "ac036f90".to!ulong(16) -> 18446744072300490640
Re: Function to print a diamond shape
On Thursday, 20 March 2014 at 22:46:53 UTC, Ali Çehreli wrote: On 03/20/2014 03:03 PM, Brad Anderson wrote: > I'm not entirely happy with it but: I am not happy with my attempt either. :) >void main() >{ > import std.algorithm, std.range, std.stdio, std.conv; > > enum length = 5; > auto rng = > chain(iota(length), iota(length, -1, -1)) Ooh. I like that. That would have never occurred to me. :) It felt kind of clumsy when I ended up with it. I don't think it shows my intent very well (repeat the range in reverse). I wish Phobos had something like a mirror() range (i.e. chain(rng, rng.retro())). >.map!((a => " ".repeat(length-a)), > (a => "#".repeat(a*2+1))) >.map!(a => chain(a[0].joiner, a[1].joiner, "\n")) >.joiner; > > writeln(rng); >} Does that compile for you? Failed for me with v2.066-devel-d0f461a: [snip] A regression? I did it on dpaste which is using 2.065 so I suspect regression. http://dpaste.dzfl.pl/71c331960cb0 > Had some trouble with the result coming out as integers instead of > something string-like. I had the same problem at one point. I will try to understand when that happens. Ali I was getting the integers when I was using character literals with repeat() rather than string literals.
Re: Function to print a diamond shape
On Thursday, 20 March 2014 at 21:25:03 UTC, Ali Çehreli wrote: This is a somewhat common little exercise: Write a function that takes the size of a diamond and produces a diamond of that size. When printed, here is the output for size 11: * *** * *** * *** * *** * *** * What interesting, boring, efficient, slow, etc. ways are there? Ali I'm not entirely happy with it but: void main() { import std.algorithm, std.range, std.stdio, std.conv; enum length = 5; auto rng = chain(iota(length), iota(length, -1, -1)) .map!((a => " ".repeat(length-a)), (a => "#".repeat(a*2+1))) .map!(a => chain(a[0].joiner, a[1].joiner, "\n")) .joiner; writeln(rng); } Had some trouble with the result coming out as integers instead of something string-like.
Re: signatures
On Friday, 21 February 2014 at 23:46:10 UTC, voyager wrote: is there some thing like typedef? alias int XXX; alias int YYY; void a1(XXX a, YYY b) {int c = a+b;} void a1(int a, YYY b) {int c = a+b;} gives an error: Building Debug\bgitest.exe... bgitest.obj : fatal error LNK1179: invalid or corrupt file: duplicate COMDAT '_D4main2a1FiiZv (void main.a1(int, int))' Building Debug\bgitest.exe failed! Details saved as "file://G:\PROGRAMMING\DPROG\bgitest\bgitest\Debug\bgitest.buildlog.html" == Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped == http://dlang.org/phobos/std_typecons.html#Typedef
Re: [video tutorial] Cleaning up our command line argument parsing code
On Thursday, 20 February 2014 at 07:06:22 UTC, simendsjo wrote: On Wednesday, 19 February 2014 at 21:55:35 UTC, Brad Anderson wrote: On Wednesday, 19 February 2014 at 14:46:57 UTC, simendsjo wrote: Spam spam http://youtu.be/ZRUcTJC0D7M Good stuff. Are you going to upload the older videos to this same channel? Is that necessary? The playlist includes the previous videos too. The only difference is that the analytics is split across several accounts..? Ah, I didn't realize the playlist did that. I was thinking it'd be hard to find the earlier videos from the newer ones if they weren't in the same channel.
Re: [video tutorial] Cleaning up our command line argument parsing code
On Wednesday, 19 February 2014 at 14:46:57 UTC, simendsjo wrote: Spam spam http://youtu.be/ZRUcTJC0D7M Good stuff. Are you going to upload the older videos to this same channel?
Re: [video tutorial] hello world using dmd, rdmd, dub and vibe.d
On Saturday, 15 February 2014 at 13:28:24 UTC, simendsjo wrote: http://youtu.be/8TV9ZZteYEU The content wasn't planned, and English is not my native tongue. Hopefully it can still be useful for newbies. This is pretty much a response to a recent discussion on the lack of documentation/tutorials: http://forum.dlang.org/post/spdddifmaacihlcum...@forum.dlang.org PS: The many delays are X going black, forcing me to switch to a different terminal and back again. Nicely done. It's a bit quiet (I had to max out my volume and put on headphones to hear).
Re: "scope attribute" vs "scope keyword" vs "scope storage class"
On Wednesday, 5 February 2014 at 15:43:45 UTC, Dicebot wrote: D documentation has rather incosistent naming for attribute groups. - scope classes are deprecated, but usage of scope as storage class is still legal (it is expected to be a no-op for now) Couldn't "scope" allocating a class on the stack just be considered an optimization that can be applied if the scope storage class become fully implemented? - scope storage class for function parameters is also accepted as no-op. For delegates it actually has a meaning. No deprecation. No-op just because it hasn't been implemented yet, right?
Re: Tyepof regex
On Monday, 13 January 2014 at 20:53:55 UTC, Tiberiu Gal wrote: what is the type returned by regex function? I want to store a regex member because I need to reuse it multiple times. Can this be done? class A { protected SomeTypeName regexPattern; void load() { string str; // obtain a regex pattern and store it as str. regexPattern = regex( str ); } bool matches() { // use regexPattern } } The type is a template called Regex that is templated on the character width. struct A { Regex!char re; this(string str) { re = regex(str); } } There is also std.traits.ReturnType you can use for more complex types or voldemort types.
Re: Compile/link Win64
On Friday, 10 January 2014 at 20:26:35 UTC, Nick Sabalausky wrote: On 1/10/2014 3:19 PM, Brad Anderson wrote: I don't have VC2008 so I unfortunately could not test while I was working on the installer/sc.ini update. Rainer says 2008 does work though. With modern VC there is a vcvars32.bat and vcvars64.bat to choose whether to use the 32-bit or 64-bit toolchain. What is the value of %WindowsSdkDir% within your vcvars.bat command prompt? Hmm, that's strange, %WindowsSdkDir% isn't set. I thought vcvarsall.bat was supposed to set up all of that. Appears to be a common problem with VC2008: http://stackoverflow.com/questions/1102689/windowssdkdir-is-not-set-correctly-in-visual-studio-2008
Re: Compile/link Win64
On Friday, 10 January 2014 at 20:02:49 UTC, Nick Sabalausky wrote: I never seem to be able to remember how to get 64-bit going on windows. I've extracted the zip for DMD 2.064.2, I ran the "vcvarsall.bat", but trying to compile this trivial hello world: import std.stdio; void main() { writeln("Hello"); } > [path_to]dmd.2.064.2\dmd2\windows\bin\dmd -m64 hello.d Gives me this: LINK : fatal error LNK1104: cannot open file 'shell32.lib' --- errorlevel 1104 On a slightly more complicated program (a simple mysql-native test program), I get this: LINK : fatal error LNK1104: cannot open file 'ws2_32.lib' --- errorlevel 1104 I also tried uncommenting the appropriate line in sc.ini: ;VC2008 LINKCMD=%VCINSTALLDIR%\bin\amd64\link.exe to: LINKCMD=%VCINSTALLDIR%\bin\amd64\link.exe But that had no effect. I don't have VC2008 so I unfortunately could not test while I was working on the installer/sc.ini update. Rainer says 2008 does work though. With modern VC there is a vcvars32.bat and vcvars64.bat to choose whether to use the 32-bit or 64-bit toolchain. What is the value of %WindowsSdkDir% within your vcvars.bat command prompt?
Re: opDispatch() is pretty damn great
On Wednesday, 8 January 2014 at 23:20:06 UTC, Szymon Gatner wrote: Still exploring what D has to offer but this blew my mind: I don't quite understand why "enum name" part is necessary (as my understanding is that "op" is compile-time constant anyway) but since I am crap at D that is what worked for me. I was thinking for log time how great something like that would be in C++ and I just tried this id D... Mind blown... std::reference_wrapper<> would be a zillion times more usable with equivalent of opDispatch() this powerful. There is also `alias this` for subtyping. import std.stdio; struct Base { void print(string text) { writeln("Base : " ~ text); } int add(int a, int b) { return a + b; } } struct Wrap { Base base; alias base this; } void baseOnly(Base b) { b.print("passed in a Wrap!"); } int main(string[] argv) { Wrap wrap; wrap.print("wrapped call, magic!"); baseOnly(wrap); auto res = wrap.add(1, 5); return 0; }
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 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: My first D module - Critiques welcome.
On Monday, 23 December 2013 at 21:34:34 UTC, John Carter wrote: So I resolved to learn D, and try code as idiomatically as I could. So here is a trivial module that encodes and decodes roman numerals. https://bitbucket.org/JohnCarter/roman/src/9ec5b36b9973426f35b0ab9dfd595cb3b305e39e/roman.d?at=default I also attempted to do it in "Best Practice Test Driven Development" form with commits on every change. So you can see the blow by blow history of how it grew. I would welcome any critique, advice, flames, recommendations, etc. etc. Thanks for your help and patience with various stupid newbie questions I asked in the process! You could also do some neat stuff with opDispatch. Someone actually wrote an article about using it with roman numerals: http://idorobots.org/2012/03/04/romans-rubies-and-the-d/
Re: Suppressing UTFException / Squashing Bad Codepoints?
On Monday, 23 December 2013 at 22:41:47 UTC, John Carter wrote: Eww. If I read the source correctly it mallocs a new array and runs down the original at least three times! (Four if you count peeks) Not to mention that it is completely unintegrated with stdio. Sigh! I miss the Good Old Days of 7-bit ASCII! ;-) Pull requests with improvements are always welcome. I don't think std.encoding gets a lot of attention.
Re: Suppressing UTFException / Squashing Bad Codepoints?
On Monday, 23 December 2013 at 20:48:08 UTC, John Carter wrote: This frustrated me in Ruby unicode too Typically i/o is the ultimate in "untrusted and untrustworthy" sources, coming usually from systems beyond my control. Likely to be corrupted, or maliciously crafted, or defective... Unfortunately not all sequences of bytes are valid UTF8. Thus inevitably in every collection of inputs there are always going to be around 1 in a million codepoints resulting in an UTFException thrown. Alas, I always have to do Regex matches on the other 99 valid codepoints. Is there a standard recipe in stdio for squashing bad codepoints to some default? These days memory is very much larger than most files I want to scan. So if I was doing this in C I would typically mmap the file PROT_READ | PROT_WRITE and MAP_PRIVATE then run down the file squashing bad codepoints and then run down it again matching patterns. In Ruby I have a horridly inefficient utility def IO.read_utf_8(file) read(file,:external_encoding=>'ASCII-8BIT').encode('UTF-8',:undef=>:replace) end What is the idiomatic D solution to this conundrum? The encoding schemes in std.encoding support cleaning up input using the sanitize function. http://dlang.org/phobos/std_encoding.html#.EncodingScheme.sanitize It'd be nicer if the API were range based but it seems to do the trick in my experience.
Re: std.net.curl - get() is too slow
On Friday, 20 December 2013 at 18:23:30 UTC, Benji wrote: When I call get() function from std.net.curl, I notice it's extremely slow! Maybe 50 times slower than in Python.. Is there any better/faster alternative? Without doing any profiling I'd say this character concatenation while decoding is probably a large source of any slowness. https://github.com/D-Programming-Language/phobos/blob/master/std/net/curl.d#L1908 Switching it to Appender or doing some sort of batch processing would probably help a lot. Even just a .reserve() would probably do wonders.
Re: Creating a class at a specific address in memory.
On Thursday, 12 December 2013 at 22:54:26 UTC, TheFlyingFiddle wrote: What i am looking for is something like the following. class Foo { int a, b, c; } void main() { void[] buffer = new void[1024]; auto foo = createAt!(Foo)(buffer.ptr); } Where the createAt!(Foo) creates a class of the type Foo at the specified pointer. emplace() is what you are looking for (found inexplicably in std.conv). http://dlang.org/phobos/std_conv.html#.emplace
Re: Is this reasonable?
On Thursday, 5 December 2013 at 19:36:46 UTC, H. S. Teoh wrote: On Thu, Dec 05, 2013 at 03:47:27PM -0300, Ary Borenszweig wrote: [...] Cough, cough, make array length be an int. Do you really need arrays that big? :-S (I'm talking to Mr. D Compiler here) A negative length array makes no sense. Plus, being a systems language, D should be able to represent an entire 64-bit address space as an array of ubytes (even if this is rarely done!). If one were to write a kernel in D, it would be laughable to use signed array lengths. T Chandler Carruth of LLVM fame (also on the C++ ISO Committee) said during Going Native (it was either his talk or the panel, I can't remember which unfortunately) that C++'s decision to make size_t unsigned was a big mistake and you should almost always use signed integers unless you need two's complement arithmetic for some weird reason. I can't remember the entire rationale for this though. http://channel9.msdn.com/Events/GoingNative/2013/The-Care-and-Feeding-of-C-s-Dragons http://channel9.msdn.com/Events/GoingNative/2013/Interactive-Panel-Ask-Us-Anything
Re: Remove function?
On Wednesday, 4 December 2013 at 22:13:52 UTC, seany wrote: does all the algorithms defined in std.string and std.algorithm also apply on char[] ? Pretty much. If one doesn't it'd be a considered a bug. front() and popFront() defined for arrays in std.array specialize for narrow strings (that is, UTF-8 and UTF-16 encoded strings whether they are immutable(char)[] or just char[]) so they evaluate by code point. This means all algorithms that make use of ranges automatically work for either case. is there any way to force a string to become mutable? You could just bash it over the head with a cast() but you should not do that. You can call .dup() to return a mutable copy of a string. I'm not actually sure how well remove() works with narrow strings though. Seems like it doesn't seem to like them in my quick test. Non-narrow strings work fine though. // http://dpaste.dzfl.pl/0a269245 void main() { import std.algorithm, std.stdio; dstring immutable_str = "this is an immutable string"d; dchar[] mutable_str = immutable_str.dup; mutable_str = mutable_str.remove(9, 11, 12); writeln(immutable_str); writeln(mutable_str); }
Re: Remove function?
On Wednesday, 4 December 2013 at 21:59:45 UTC, seany wrote: Hello, I want to remove a car form a string. hence i used the remove function from std.algorithm, and i had this : string stripPar(string S) { while(S[0] == '(' && S[S.length-1] == ')') { S = S.remove(0); S = S.remove(S.length-1); } return S; } string is defined as: alias string = immutable(char)[]; This means the string contents cannot be changed because the individual characters are immutable. If you'd like to modify the string I'd use a char[] in place of string.
Re: Accessing a Hash table as a Value-Sorted Range
On Tuesday, 19 November 2013 at 21:11:42 UTC, Nordlöw wrote: If I have a hash-table `File[string] _subs` and want to access its values in a sorted way is there a better than simply through auto ssubs = new File[_subs.length]; // preallocate sorted subs size_t ix = 0; foreach (sub; _subs) { ssubs[ix++] = sub; // set new reference to sub } ssubs.sort!((a, b) => (a.timeLastModified > b.timeLastModified)); return ssubs; You could switch to a RedBlackTree which is sorted and offers somewhat fast lookup. Other than that, I'd say what you are doing is already about as good as you can get.
Re: returning different types via function
On Tuesday, 19 November 2013 at 19:15:10 UTC, seany wrote: Consider this: I have a function FUNC, it takes a string array, and does something with it, and retruns the same. Implemented based on a previous thread, here is what i have string[] FUNC (ref string[] ZZ) { /* do something */ } and the calling is, ZZ = FUNC(ZZ) Now, I want, should the function be not successful in doing what it intends to do, to return a boolean value of false, to ZZ, un fortunately ZZ is already a string[] (so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false) Is this possible in D? You could use std.typecons.Nullable, std.variant.Variant, or switch to using exceptions for error reporting.
Re: Optional equivalent in D?
On Friday, 15 November 2013 at 22:41:40 UTC, Brad Anderson wrote: On Friday, 15 November 2013 at 22:39:40 UTC, Jacek Furmankiewicz wrote: Many other languages are starting to frown on returning null values from methods (due to NullPointerException risks, etc) and wrapping them instead in an Optional like in Scala: http://blog.danielwellman.com/2008/03/using-scalas-op.html Google Guava for Java: (now rolled into the base JDK for Java 8): https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained Is there a similar approach in D? Or maybe an equivalent is in a commonly used external library? Sounds like std.typecons.Nullable to me. I recommend having a look around std.typecons while you are in there. It's got a lot of gems that seem to go unnoticed by a lot of people.
Re: Optional equivalent in D?
On Friday, 15 November 2013 at 22:39:40 UTC, Jacek Furmankiewicz wrote: Many other languages are starting to frown on returning null values from methods (due to NullPointerException risks, etc) and wrapping them instead in an Optional like in Scala: http://blog.danielwellman.com/2008/03/using-scalas-op.html Google Guava for Java: (now rolled into the base JDK for Java 8): https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained Is there a similar approach in D? Or maybe an equivalent is in a commonly used external library? Sounds like std.typecons.Nullable to me.
Re: Efficient string concatenation?
On Friday, 15 November 2013 at 22:26:20 UTC, Jacek Furmankiewicz wrote: Since D strings are immutable (like in most other languages), string concatenation is usually pretty inefficient due to the need to create a new copy of the string every time. I presume string concatenation using the typical array syntax can be optimized by the compiler to do all of this in one shot, e..g string newString = string1 ~ string2 ~ string3; but what happens if I need to concatenante a large string in a loop? I tried looking through Phobos for a StringBuilder class (since that is the common solution in Java and C#), but did not find anything similar. What is the D way of doing efficient string concatenation (especially if it spans multiple statements, e.g. while in a loop)? Appender in std.array is probably what you are looking for. std.algorithm.joiner is also useful (no allocations at all even) but the use case is a bit different.
Re: Dynamic array handling
On Thursday, 14 November 2013 at 21:38:39 UTC, seany wrote: In Very High level languages, such as scilab, you can write array_var = (1,2,3 ... etc) and then you can also write array_var = array_var(1:2,4:$) In this case, the third element is dropped, and the same variable, array_var is set to be an array of a different length, resizing of array and so on is automated. Is the same possible to be done in D? say, int [] a ; //initialize; a ~= 1; a ~= 2; //etc, polulate . . . say, we fill up 10 such elements Now, can you do like, a = somefunction_that_drops_the_4th_element(a); // a is reset, // and the length // is reorganized automatically a = a.remove(3);
Re: Cannot cast char[] to string.
On Thursday, 14 November 2013 at 19:41:13 UTC, Agustin wrote: I'm trying to use http://dlang.org/phobos/std_net_curl.html and when i compile the same example i get: cannot implicitly convert expression (get(cast(const(char)[])address, AutoProtocol())) of type char[] to string string address = "http://dlang.org";; string _data = get(address); You have two options: string address = "http://dlang.org";; string _data = get(address).idup(); // create immutable copy or string address = "http://dlang.org";; char[] _data = get(address); // store mutable reference A string (which is just an alias of immutable(char)[]) can't be made from a char[] without an assertion that the data pointed to is, in fact, immutable. You can do that using assumeUnique (inexplicably found in std.exception).
Re: Just noticed something interesting in the std.allocator source...
On Friday, 25 October 2013 at 16:03:24 UTC, Gary Willoughby wrote: Just noticed something interesting in the std.allocator source, right at the very bottom. An EOF and some code? Does the compiler stop at the EOF? If so why add code beyond that? Also version(none), eh? https://github.com/andralex/phobos/blob/allocator/std/allocator.d#L4071 What's going on there? ... __EOF__ version(none) struct TemplateAllocator { enum alignment = platformAlignment; static size_t goodAllocSize(size_t s) { } void[] allocate(size_t) { } bool owns(void[]) { } bool expand(ref void[] b, size_t) { } bool reallocate(ref void[] b, size_t) { } void deallocate(void[] b) { } void deallocateAll() { } void[] allocateAll() { } static shared TemplateAllocator it; } Yeah, it sets the lexer to the end of file so it stops. See Special Tokens section: http://dlang.org/lex.html Andrei is using it to include a pattern of the general structure you'd need to write your own allocator that the compiler doesn't even bother looking at. He could have commented it out too. The version(none) also accomplishes this. __EOF__ just makes it so the compiler doesn't even bother looking at it (you can shave a few microseconds off your build time!)
Re: How to add time to Clock.currTime
On Friday, 4 October 2013 at 21:46:43 UTC, JohnnyK wrote: Hi All, I did search but I cannot find it anywhere. All I want to do is add 300 seconds to the output of Clock.currTime. So basically if Clock.currTime equals 2013-Oct-04 17:19:31.3338333 then I want to subtract 300 seconds from that to get the time that it was 300 seconds ago. In other languages I would convert the time value to seconds and subtract the 300 seconds then convert it back to what ever time value it was before. I don't know how to convert 300 seconds to hnsecs and I have never actually heard of hnsecs before. Anyway if someone could help I would appreciate it. auto t = Clock.currTime; t -= 300.seconds; t += 300.seconds;
Re: How to add time to Clock.currTime
On Friday, 4 October 2013 at 21:50:31 UTC, Brad Anderson wrote: On Friday, 4 October 2013 at 21:46:43 UTC, JohnnyK wrote: Hi All, I did search but I cannot find it anywhere. All I want to do is add 300 seconds to the output of Clock.currTime. So basically if Clock.currTime equals 2013-Oct-04 17:19:31.3338333 then I want to subtract 300 seconds from that to get the time that it was 300 seconds ago. In other languages I would convert the time value to seconds and subtract the 300 seconds then convert it back to what ever time value it was before. I don't know how to convert 300 seconds to hnsecs and I have never actually heard of hnsecs before. Anyway if someone could help I would appreciate it. auto t = Clock.currTime; t -= 300.seconds; t += 300.seconds; And just a little bit more info, another way to write this is: auto t = Clock.currTime; t -= seconds(300); t += seconds(300); The first way I wrote is just the UFCS version of that. You could also do: auto t = Clock.currTime; t -= dur!"seconds"(300); t += dur!"seconds"(300); seconds() is just an alias for the dur template with the "seconds" template argument.
Re: std.algorithm's remove
On Sunday, 25 August 2013 at 02:24:30 UTC, maarten van damme wrote: hello, I'm a hobyist-programmer and around where I live there's a group of haskell fanatics. They posted solutions to a recent programming challenge which I find to be a bit ugly. For fun I wanted to implement it in d and a rough version (not correct yet, this was written/hacked in 5 minutes after reading the exercise) My rough version is posted here : http://dpaste.dzfl.pl/4b5a6578 if you look at the output, you'll see this particular line : "omkom -> komkom because of : kom momkom momkom -> momkomm" This is because of what remove from std.algorithm does. It not only returns a range with that element removed (as the name implies), it also modifies the original range. I assume this decision was made for efficiency purposes but that is one of the most ugliest things I have ever come across. At least c# forces the 'ref' in it's parameters so you know something's up. Is there any way I could've known this? (apart from reading the documentation on every single trivial function in the std library?) It was done that way intentionally because the purpose of remove is to remove from the source range. If you don't want to affect the source range use filter. I suspect you could trace remove's lineage back to C++ STL's remove which works similarly (but is significantly clunkier and harder to use).
Re: How to change DList elements by means of foreach?
On Monday, 10 September 2012 at 13:05:16 UTC, monarch_dodra wrote: On Monday, 10 September 2012 at 12:44:36 UTC, Alexandr Druzhinin wrote: 10.09.2012 18:37, monarch_dodra пишет: There is a know bug: foreach with ref does not currently work these containers. The reason is that the container's front does not actually expose a reference, but a value, and that is what is being changed (the returned value). There is no hope in sight to really *ever* make it work, because "container.front += 5" can't be made to work if the returned value is not a reference: Unlike indexes that define opIndexOpAssign, there is no opFrontOpAssign. What bothers *me* though is that the code compiles fine, biting more than 1 user in the process. Anyways... the workaround is* making an explicit loop, with temporary object that is fed back into front, like this: import std.container; void main() { // double-linked list; DList!int dlist; dlist.insertFront(0); auto slice = dlist[]; //Extract a range manually for( ; !slice.empty ; slice.popFront() ) { auto value = slice.front; //Extract the value value += 50; //Increment the value slice.front() = value;//Feed back into the range* } foreach(value; dlist) { assert(value == 50); //Now this works fine } } Well... this *would* work, but apparently, the implementation of DList.Range doesn't define front(T value). This makes the Range pretty much read-only. My guess is that this was an omission on the part of the implementer. I will fix it so that it works. Good to know, but bad to do... If in std.container: 1553:@property T front() { return _first._payload; } change to: 1553:@property *ref* T front() { return _first._payload; } doesn't it solve the problem or I don't know/understand something else? Arguably yes, however, the idea is that a container is supposed to have an implementation defined allocator, meaning that operations "may or may mot" invalidate references. So it is not allowed to return a reference. IMO, this is a valid argument for things like Array, that "can and will" move objects around, without ever telling the accessing ranges. Giving reference access here would be most dangerous. Not impossible, but very unsafe, and Phobos strives to be safe. The same argument applies to BinaryHeap, which is just a container adaptor. However, for any "node" based structure (such as {SD}List), which are structures that users usually chose *because* references are *always* valid, the argument doesn't hold as well. In particular, even with an implementation defined allocator, there is no reason a reference can't be returned. I'll try to push for reference access, but I may be turned down on the simple argument of "container uniformity" :/ Finally, regarding RedBlackTree, technically, you shouldn't assign to a node in the tree, but rather remove re-insert, so that is a non-issue. Has anything happened since this question was asked that moves toward fixes this? I just hit it myself with std.container.Array. How is anyone supposed to do anything productive with std.container containers with this glaring limitation? I'm kind of surprised std.container is even included with phobos with such a deficiency. Does anyone actually use these containers?
Re: Generating members from parameter tuple
On Monday, 19 August 2013 at 16:40:45 UTC, Dicebot wrote: On Monday, 19 August 2013 at 06:56:24 UTC, Brad Anderson wrote: ... I remember asking Andrei on IRC about feature as "declaration foreach" to exactly simplify such patterns. He kind of agreed it may be useful and wanted to consult with Walter if it is worth a DIP but seems like everyone including me has forgot it :) In a meanwhile, here is a recursive template-based alternative: http://dpaste.dzfl.pl/f9def804 Ok, that helps me understand how to do it with recursion and mixin templates. I ended up doing it like this: http://dpaste.dzfl.pl/14864b1b with help from Jakob Ovrum in IRC.
Re: Generating members from parameter tuple
On Monday, 19 August 2013 at 16:22:21 UTC, John Colvin wrote: On Monday, 19 August 2013 at 06:56:24 UTC, Brad Anderson wrote: import std.typetuple; struct S(T...) { alias Types = T; } alias Si = S!(int, short); alias Sf = S!(float, double); template STypes(STy) { alias STypes = STy.Types; } struct B(Ss...) { alias CombinedTypes = NoDuplicates!(TypeTuple!(staticMap!(STypes, Ss))); // I'd like to create a member here for every type in CombinedTypes // that is an array of each type. e.g., // int[]_intArray; // short[] _shortArray; // float[] _floatArray; // double[] _doubleArray; // // I don't believe the names matter because I'd probably want // to use a templated method that returns the appropriate // member based on the type supplied (e.g., getArray!int(), // getArray!short(), etc.) } Take a look at the implementation of std.typetuple.Tuple, it does something similar. I actually looked there first but it parses the types to support named parameters so it was much more complicated than I could use.
Re: Generating members from parameter tuple
On Monday, 19 August 2013 at 06:56:24 UTC, Brad Anderson wrote: import std.typetuple; struct S(T...) { alias Types = T; } alias Si = S!(int, short); alias Sf = S!(float, double); template STypes(STy) { alias STypes = STy.Types; } struct B(Ss...) { alias CombinedTypes = NoDuplicates!(TypeTuple!(staticMap!(STypes, Ss))); // I'd like to create a member here for every type in CombinedTypes // that is an array of each type. e.g., // int[]_intArray; // short[] _shortArray; // float[] _floatArray; // double[] _doubleArray; // // I don't believe the names matter because I'd probably want // to use a templated method that returns the appropriate // member based on the type supplied (e.g., getArray!int(), // getArray!short(), etc.) } For got to add a B!(Si, Sf) somewhere (I had a main() but stripped it out).
Generating members from parameter tuple
import std.typetuple; struct S(T...) { alias Types = T; } alias Si = S!(int, short); alias Sf = S!(float, double); template STypes(STy) { alias STypes = STy.Types; } struct B(Ss...) { alias CombinedTypes = NoDuplicates!(TypeTuple!(staticMap!(STypes, Ss))); // I'd like to create a member here for every type in CombinedTypes // that is an array of each type. e.g., // int[]_intArray; // short[] _shortArray; // float[] _floatArray; // double[] _doubleArray; // // I don't believe the names matter because I'd probably want // to use a templated method that returns the appropriate // member based on the type supplied (e.g., getArray!int(), // getArray!short(), etc.) }
Re: does pointer refer to a heap object?
On Saturday, 27 July 2013 at 17:58:20 UTC, Carl Sturtivant wrote: Given a pointer to a struct, is there a clean way to determine if that struct is allocated on the heap or not? Or alternatively to determine whether it has finite or infinite lifetime (in TDPL speak)? import core.memory, std.stdio; struct A { } void main() { A a; auto ap = &a; auto bp = new A; writeln("ap", GC.addrOf(ap) ? "" : " not", " allocated with the GC"); writeln("bp", GC.addrOf(bp) ? "" : " not", " allocated with the GC"); } Note that the heap is more than just GC allocated memory. C malloc allocates on the heap but would fail the above test (as it should).
Re: ref tuples
On Wednesday, 3 July 2013 at 16:35:18 UTC, Artur Skawina wrote: On 07/03/13 18:29, Brad Anderson wrote: On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote: On 07/03/13 02:22, Brad Anderson wrote: C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple? Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2); That won't work. a and b aren't held as references (also you passed them as type parameters :P). Try it... And, yes, the fact that 'A...' template parms accept symbols is not exactly obvious. But it's much more useful that way. artur Huh, I had no idea you could do something like that. I stand corrected. Thanks. That does get tie = working but doesn't work if you want to pass it around which is actually more at the heart of what I'm interested in. To get straight to the point, I was playing around with implementing bearophile's enumerate() feature request (something I've wanted myself). Both his posted solution [1] and my own quick testing hack (auto enumerate(Range)(Range r) { return zip(sequence!"n"(), r); }) lose the ability to do ref elements in foreach that can modify the source range: --- auto a = ["a", "b", "c"]; foreach(i, ref item; a.enumerate()) item = to!string(i); assert(a == ["0", "1", "2"]); // fails, a is still ["a", "b", "c"] --- They don't work because both the tuples he returns from front and the tuples zip creates aren't references to the originals so you are just changing the copy stored in the tuple. Something like "alias RefIntTuple = Tuple!(ref int, ref int);" gives a compiler error (Error: expression expected, not 'ref'). 1. http://d.puremagic.com/issues/show_bug.cgi?id=5550#c2
Re: ref tuples
On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote: On 07/03/13 02:22, Brad Anderson wrote: C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple? Well, aliases can be used to get a similar effect. template tie(A...) { alias tie = A; } tie!(a, b) = tuple(1, 2); artur That won't work. a and b aren't held as references (also you passed them as type parameters :P).
ref tuples
C++11's std::tuple includes a function std::tie that takes references to the arguments and returns a tuple that maintains the references to the arguments. Along with the usual cases where you'd want reference semantics it also enables this interesting construct for unpacking tuples. int a, b; tie(a, b) = make_tuple(1, 2); assert(a == 1 && b == 2); Is there any way to do something similar with std.typecons.Tuple?
Re: counting words
On Friday, 28 June 2013 at 19:31:22 UTC, monarch_dodra wrote: On Friday, 28 June 2013 at 19:13:28 UTC, Brad Anderson wrote: 95 merged phobos pull requests (109 total). Long overdue, I'd say. I don't know if there is really a formal process to getting write privileges but if any of the people who decide are reading this I nominate monarch_dodra. How did you come to that number? Total amount of pulls *submitted* ? I count 95 *closed* pull requests, but I think only about 50% of them ever made it through? I'm not sure how to check though (apart from counting 1 by 1...) I'm unsure I'd be totally comfortable pulling inside phobos, but it *is* true that the queue is just getting longer and longer. There are some pulls just sitting there, submitted by trusted people (with pull rights), that are validated and reviewed, but are just waiting for a puller to do the deed. There needs to be a few more reviewers, the ones we have are doing a great job, but are overworked. But I wouldn't want to hijack this thread, nor is learn really the place to talk about that. I counted closed (I assumed most were merged). Github makes it hard to glean data from pull requests. Allow me to share Exhibit B though: https://github.com/D-Programming-Language/phobos/graphs/contributors?from=2012-06-21&to=2013-06-21&type=c Second most prolific contributor by commits to phobos over the last year. I am nominating you to do extra bureaucratic work though so I'm kind of being an asshole when you think about it. :P
Re: counting words
On Friday, 28 June 2013 at 18:53:44 UTC, monarch_dodra wrote: On Friday, 28 June 2013 at 17:59:58 UTC, bearophile wrote: monarch_dodra: Well, I've had a PR open for this for about 8 months now... Do you have Phobos commit rights? If the answer is positive then perhaps you can review and commit some Phobos code written by Andrei and he can do the same with yours. Today it seems the major development bottleneck is the review queue and not having enough writing of patches :-) Bye, bearophile The answer is negative though :( 95 merged phobos pull requests (109 total). Long overdue, I'd say. I don't know if there is really a formal process to getting write privileges but if any of the people who decide are reading this I nominate monarch_dodra.
Re: counting words
On Friday, 28 June 2013 at 16:48:08 UTC, Benjamin Thaut wrote: Am 28.06.2013 18:42, schrieb Brad Anderson: On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)=> a[1] > b[1]) .map!(a => a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] > dic[b]; return less || less && a < b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts. I figured something like this by now too. Thank you. But I don't quite understand what the copy is for at the end? Just replacing your original word list with the sorted list (which I just realized is wrong because it will leave a bunch of words on the end, oops). You could .array it instead to get a new array or just store the range with auto and consume that where needed with no extra array allocation.
Re: counting words
On Friday, 28 June 2013 at 16:25:25 UTC, Brad Anderson wrote: On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)=> a[1] > b[1]) .map!(a => a[0]) .copy(words); You could also do it with a hashmap to keep the count. Like so: size_t[string] dic; words.map!((w) { ++dic[w.idup]; return w; }) .array // eager (so dic is filled first), sortable .sort!((a, b) { bool less = dic[a] > dic[b]; return less || less && a < b; }) .uniq .copy(words); It's a bit ugly and abuses side effects with the hash map. The order will differ from the other program when words have identical counts.
Re: counting words
On Friday, 28 June 2013 at 16:04:35 UTC, Benjamin Thaut wrote: I'm currently making a few tests with std.algorithm, std.range, etc I have a arry of words. Is it possible to count how often each word is contained in the array and then sort the array by the count of the individual words by chaining ranges? (e.g. without using a foreach loop + hashmap)? If you don't mind sorting twice: words.sort() .group() .array() .sort!((a, b)=> a[1] > b[1]) .map!(a => a[0]) .copy(words); You could also do it with a hashmap to keep the count.
Re: Opaque structs
On Friday, 28 June 2013 at 01:40:44 UTC, Andrej Mitrovic wrote: Note that if we implement Issue 8728[1], we could even create a better error message via: - struct S { @disable("S is an opaque C type and must only be used as a pointer") this(); @disable("S is an opaque C type and must only be used as a pointer") this(this); } void main() { S* s1; // ok S s2; // user error } - [1] : http://d.puremagic.com/issues/show_bug.cgi?id=8728 +1. Anything that makes error messages clearer is a win in my book and there is precedents for it in @deprecate(msg) which was a clear win.
Re: Consume an entire range
On Thursday, 30 May 2013 at 11:38:58 UTC, bearophile wrote: Brad Anderson: import std.stdio, std.algorithm, std.array; void eat(R)(R r) { while(!r.empty) { r.front; r.popFront; } } void main() { size_t[dstring] dic; stdin.byLine .joiner(" ") .array .splitter(' ') .filter!(w => !w.empty && w !in dic) .map!(w => writeln(dic[w.idup] = dic.length, '\t', w)) .eat; } I would have prefered to not use joiner() but working with ranges of ranges of ranges (splitter() on each line) got a bit weird and confusing. Maybe here it's better to work on lines. Alternatively I don't know if you can read the whole input there. I posted a version that worked on lines instead. I was having trouble but the trouble was actually the same problem I was having with the joined version (my map wasn't being consumed). It's usually better to give only pure functions to filter/map, because in Bugzilla I've shown those higher order functions don't work well otherwise. Have any links? I considered using sort and uniq to avoid the closure around dic but then the order would be different and I wanted to keep it using a similar technique to the original. So I prefer a terminal function that takes an impure function and returns nothing, something like: ... .filter!(w => !w.empty && w !in dic) .forEach!((w) { writeln(dic[w.idup] = dic.length, '\t', w); }); Is forEach real? I sought it out because it'd be a better fit but came up empty (it's not in std.range or std.algorithm). Bye, bearophile
Re: Consume an entire range
On Thursday, 30 May 2013 at 04:30:11 UTC, Brad Anderson wrote: [snip] import std.stdio, std.algorithm, std.array; void eat(R)(R r) { while(!r.empty) { r.front; r.popFront; } } void main() { size_t[dstring] dic; stdin.byLine .joiner(" ") .array .splitter(' ') .filter!(w => !w.empty && w !in dic) .map!(w => writeln(dic[w.idup] = dic.length, '\t', w)) .eat; } I would have prefered to not use joiner() but working with ranges of ranges of ranges (splitter() on each line) got a bit weird and confusing. Ok, I guess it's not that weird after all: void main() { size_t[string] dic; stdin.byLine .map!(l => l.splitter(' ') .filter!(w => !w.empty && w !in dic) .map!(w => writeln(dic[w.idup] = dic.length, '\t', w)).eat).eat; }
Re: Consume an entire range
On Thursday, 30 May 2013 at 04:12:56 UTC, Diggory wrote: On Thursday, 30 May 2013 at 03:53:06 UTC, Brad Anderson wrote: On Thursday, 30 May 2013 at 03:50:52 UTC, Brad Anderson wrote: Is there a simple way to consume a range apart from std.array.array? I don't need to result of the range stored in an array, I just need a lazy map to evaluate completely. Obviously I could just popFront. To be more clear, I want something like eat() or consume() or exhaust() that I can tack on the end of my chained algorithm calls. There's "walkLength"? I tried that. There is an isInputRange && !isInfinite template constraint but I don't see how my stuff didn't meet that requirement.
Re: Consume an entire range
On Thursday, 30 May 2013 at 04:00:39 UTC, Jonathan M Davis wrote: On Thursday, May 30, 2013 05:53:02 Brad Anderson wrote: On Thursday, 30 May 2013 at 03:50:52 UTC, Brad Anderson wrote: > Is there a simple way to consume a range apart from > std.array.array? I don't need to result of the range stored > in > an array, I just need a lazy map to evaluate completely. Obviously I could just popFront. To be more clear, I want something like eat() or consume() or exhaust() that I can tack on the end of my chained algorithm calls. If you specifically want to iterate over it, then I think that you need to repeatedly call popFront (or callPopFrontN if it hasLength). However, if what you want is for the resultant range to be empty, you can use std.range.takeNone. If it can, it'll return the same range type as the original, and if it can't, it'll return takeExactly(range, 0). - Jonathan M Davis There was a filter in the change so I had no length. The tailing map had a void element type which mean foreach didn't work on it. I ended up with: void eat(R)(R r) { while(!r.empty) { r.front; r.popFront(); } } I was actually just playing around reimplementing Andrei's example from his InformIT article[1] using std.algorithm and friends. It went from: import std.stdio, std.string; void main() { uint[string] dic; foreach (line; stdin.byLine) { // Break sentence into words string[] words = split(strip(line)); // Add each word in the sentence to the vocabulary foreach (word; words) { if (word in dic) continue; // nothing to do uint newID = dic.length; dic[word] = newID; writeln(newID, '\t', word); } } } to: import std.stdio, std.algorithm, std.array; void eat(R)(R r) { while(!r.empty) { r.front; r.popFront; } } void main() { size_t[dstring] dic; stdin.byLine .joiner(" ") .array .splitter(' ') .filter!(w => !w.empty && w !in dic) .map!(w => writeln(dic[w.idup] = dic.length, '\t', w)) .eat; } I would have prefered to not use joiner() but working with ranges of ranges of ranges (splitter() on each line) got a bit weird and confusing. splitter() needed array slicing and length which joiner() doesn't have so I had to use array(). I was confused about why I was suddenly getting dchar[] out the other end but found the StackOverflow question [2] in which you explain why joiner does that (you really kick ass at answering StackOverflow questions, Jonathan). Having a variant of splitter that ignores empty tokens would be nice to have too. 1. http://www.informit.com/articles/article.aspx?p=1381876&seqNum=4 2. http://stackoverflow.com/questions/12288465/std-algorithm-joinerstring-string-why-result-elements-are-dchar-and-not-ch
Consume an entire range
Is there a simple way to consume a range apart from std.array.array? I don't need to result of the range stored in an array, I just need a lazy map to evaluate completely.