Re: String Comparison Operator
On Sunday, 30 April 2017 at 19:05:18 UTC, bauss wrote: On Sunday, 30 April 2017 at 16:15:41 UTC, Xinok wrote: On Sunday, 30 April 2017 at 15:31:39 UTC, Jolly James wrote: Is there a String Comparison Operator in D? Yeah, just the usual comparison operators: "abc" == "abc" "abc" != "ABC" ~ is for string concatenation, i.e.: "abc" ~ "def" == "abcdef" Just to clarify. It's not actually a string concatenation operator, it's an array appending operator. Strings are just an alias for immutable(char)[] and not actually a type unlike other languages like C#, Java etc. where strings are objects. In fact it doesn't have any operators that doesn't work with any other type of arrays. Just like functions such as replace etc. aren't necessarily string functions, but works with any type of arrays. Regarding concatenation vs appending, it's kind of both depending on the type of the operands. What I mean is all of the following are valid: [10, 20] ~ [30, 40] == [10, 20, 30, 40] // Concatenation [10, 20] ~ 30 == [10, 20, 30] // Appending 10 ~ [20, 30] == [10, 20, 30] // Prepending
Re: String Comparison Operator
On Sunday, 30 April 2017 at 15:31:39 UTC, Jolly James wrote: Is there a String Comparison Operator in D? Yeah, just the usual comparison operators: "abc" == "abc" "abc" != "ABC" ~ is for string concatenation, i.e.: "abc" ~ "def" == "abcdef"
Re: Why double not? (!!)
On Saturday, 19 November 2016 at 03:52:02 UTC, Ryan wrote: Why do I see double `not` operators sometimes in D code? An example it the last post of this thread. http://forum.dlang.org/thread/ktlpnikvdwgbvfaam...@forum.dlang.org import core.sys.windows.windows : GetConsoleCP; bool hasConsole = !!GetConsoleCP(); Thanks. It's a more concise way of writing: GetConsoleCP() != 0 You can do this in C/C++ as well (and presumably some other languages).
Re: @nogc inconsistent for array comparison depending on mutability of elements
On Friday, 8 April 2016 at 10:15:10 UTC, Dicebot wrote: On Friday, 8 April 2016 at 09:56:41 UTC, Nick Treleaven wrote: Semantically, array literals are always allocated on the heap. In this case, the optimizer can obviously place the array on the stack or even make it static/global. So @nogc is enforced by the optimizer? Yes, sadly. What? O_o I stated that it's not and explained why doing so would be a bad idea. To make it sane one would need to make a list of all optimization DMD makes in that regard and put them into spec as mandatory for all compilers.
Re: @nogc inconsistent for array comparison depending on mutability of elements
On Friday, 8 April 2016 at 01:36:18 UTC, rcorre wrote: @nogc unittest { int[2] a = [1, 2]; assert(a == [1, 2]); // OK immutable(int)[2] b = [1, 2]; assert(b == [1, 2]); // fail: array literal may cause allocation } Is there any logic behind allowing the comparison with `a` but not `b`, or is this a compiler bug? Semantically, array literals are always allocated on the heap. In this case, the optimizer can obviously place the array on the stack or even make it static/global. However, it would be in poor design to rely on the optimizer to satisfy @nogc. It comes down to portability; if the code compiles successfully with one compiler, then it should compile successfully in any other compiler. Also, the way that compilers are typically built is that semantic analysis is done in the frontend and optimization is done in the backend. Trying to build a bridge between these two would be incredibly difficult and make implementing the compiler much more complex with little gain.
Re: How to sort a range
On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote: Still curious as to why it fails; maybe the range is getting copied at some point? I guess I need to step through it. That's my suspicion as well. It seems that OnlyResult is pass-by-value so every time it gets passed to another function, it creates a copy of all the elements. A simple solution is to provide a wrapper type which refers to the elements in the original container. However, I'm going to argue that the sort function is fine but the modifications you made to OnlyResult are incorrect. I tried running your example of only(...).sort but got a compilation error. Similarly, trying to sort a static array also gives a compilation error. However, if I slice the static array before passing it to sort (thus passing by reference), then it works just fine.
Re: How to force evaluation of range?
On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist wrote: So I have this code and I have to add the element .each!(a => a.each!("a")); to the end in order for it to evaluate the range completely and act like I expect it too. Is there a better thing to put in the place of .each!(a => a.each!("a"));? ... The following combination might work: .joiner.each; http://dlang.org/phobos/std_algorithm_iteration.html#.joiner http://dlang.org/phobos/std_algorithm_iteration.html#.each
Re: How to force evaluation of range?
On Saturday, 13 February 2016 at 01:11:53 UTC, Nicholas Wilson wrote: ... If you just want the range evaluated use walkLength It might work in this case, but in general this won't work for any range which defines .length as a member. In that case, walkLength will simply return .length of that range.
Re: How to force evaluation of range?
On Saturday, 13 February 2016 at 03:16:09 UTC, cym13 wrote: On Saturday, 13 February 2016 at 02:17:17 UTC, Xinok wrote: On Friday, 12 February 2016 at 20:43:24 UTC, Taylor Hillegeist wrote: So I have this code and I have to add the element .each!(a => a.each!("a")); to the end in order for it to evaluate the range completely and act like I expect it too. Is there a better thing to put in the place of .each!(a => a.each!("a"));? ... The following combination might work: .joiner.each; http://dlang.org/phobos/std_algorithm_iteration.html#.joiner http://dlang.org/phobos/std_algorithm_iteration.html#.each Why not just .each; ? The thing he's trying to iterate over is a range of ranges. A single .each will only iterate over the outermost range so you need .joiner first to "flatten" the range, then you can use .each on that result.
Re: Collapsing n-dimensional array to linear (1 dimensional)
On Friday, 22 January 2016 at 12:07:11 UTC, abad wrote: Let's say I have an array like this: int[][][] array; And I want to generate a linear int[] based on its data. Is there a standard library method for achieving this, or must I iterate over the array manually? What I'm thinking of is something like this: int[] onedim = std.array.collapse(array); You can use std.algorithm.joiner but you have to call it twice to flatten a 3D array to a 1D array. import std.algorithm, std.stdio, std.array; void main() { int[][][] arr = [[[1], [2, 3]], [[4, 5], [6, 7]], [[8], [9, 10], [11]]]; int[] arr2 = arr.joiner.joiner.array; writeln(arr); writeln(arr2); } http://dlang.org/phobos/std_algorithm_iteration.html#.joiner
Re: Balanced match with std.regex
On Tuesday, 15 December 2015 at 01:29:39 UTC, Jakob Ovrum wrote: Thanks, that makes sense. String manipulation in D without regex is pretty nice anyway, so it's not a big loss. There is a library named Pegged which can match against balanced parens: https://github.com/PhilippeSigaud/Pegged
Re: D programming video tutorial
On Sunday, 13 December 2015 at 20:29:47 UTC, Pederator wrote: Hi. Does anybody who is familair with D consider to make a comprehensive D programming video tutorial / training / course? This could be encouraging and helpful for people to start with D. It could also help in promoting D programming language. This is a question for all the community, please comment what do you think about this idea, we will know if there is an interest in such a training video, or is it just me. It's almost two years old now but I found this series of videos on D: https://www.youtube.com/playlist?list=PL-zvF7DyWePQad_E6Y9J9kbYvM7AjnBD1
Re: functional way doing array stuff/ lambda functions
On Saturday, 12 December 2015 at 23:36:43 UTC, cym13 wrote: ... So, in your example: int product(const ref int[] arr) { import std.array: array; import std.algorithm: reduce; arr = arr.reduce!((p, i) => p*i).array; } A good post overall but you got reduce wrong. In D, reduce computes and returns the result immediately, not a lazy range. The following code is correct: int product(const ref int[] arr) { import std.array: array; import std.algorithm: reduce; return arr.reduce!((p, i) => p*i)(); } Example: http://dpaste.dzfl.pl/fc2c2eab2d02
Re: Purity of std.conv.to!string
On Saturday, 26 September 2015 at 17:08:00 UTC, Nordlöw wrote: Why is the following code not pure: float x = 3.14; import std.conv : to; auto y = x.to!string; ??? Is there a reason for it not being pure? If not, this is a serious problem as this is such a fundamental function. I don't know the exact reason but I found a couple of functions which could be marked pure which are not, including strippedOctalLiteral and isOctalLiteralString. It's possible that some function was simply overlooked and needs to be marked pure or infer purity. The larger issue at hand is that the compiler doesn't tell you where an impurity lies, merely that it exists. I mentioned this issue not too long ago while experiencing my own difficulties respecting purity.
Re: foreach multiple loop sugar
On Tuesday, 18 August 2015 at 15:51:55 UTC, ixid wrote: Though sugar seems to be somewhat looked down upon I thought I'd suggest this- having seen the cartesianProduct function from std.algorithm in another thread I thought it would be an excellent piece of sugar in the language. It's not an earth shattering change but it makes something very common more elegant and reduces indentation significantly for multiple nested loops. Braces make nested loops very messy and any significant quantity of code in the loop body benefits from not being in a messy nesting. ... What's wrong with just putting all the foreach statements on a single line? foreach(i; 0..10) foreach(j; 0..10) foreach(k; 0..10) { writeln(i, j, k); }
Re: Does D have syntax for adding subscopes to classes?
On Wednesday, 12 August 2015 at 15:47:37 UTC, Adam D. Ruppe wrote: Example with them: ... That's the idea I had except I would use a struct instead because using a class requires a second allocation.
Is Key Type?
is there a trait in D or Phobos which will tell you if a type can be used as a key for an associative array? For example, where T is some type: static assert(isKeyType!T) int[T] hashTable = ...
Re: Map Purity
On Sunday, 28 June 2015 at 15:55:51 UTC, jmh530 wrote: My understanding of pure is that a function labeled pure can only include pure functions. I've been confused by the fact that a function calling map (like below) can be labeled pure without any problems. The only way I can rationalize it is that map really isn't a function, it's (if I'm understanding it correctly) a template that creates a template function that calls a struct template. auto test_map(T)(T x) pure { return x.map!(a = a + a); } This is related to http://forum.dlang.org/thread/ppmokalxdgtszzllz...@forum.dlang.org?page=1 but maybe my question is more basic. Map isn't explicitly marked as pure. D can infer purity for templated functions, so as long as you give it a pure predicate, map can be inferred as pure. This only works for templated functions; non-templated functions must be explicitly marked as pure.
Re: Associative array on the heap
On Tuesday, 19 May 2015 at 00:31:50 UTC, Freddy wrote: Sorry mis-phrased my question, Who do you allocate a pointer to an associative array(int[string]*). Ignoring the why for a moment, one trick is to place it in an array literal so it's heap allocated. This requires writing an associative array literal with a single key-element pair though. int[string]* a = [[zero:0]].ptr; Another trick is to initially define the associative array in a class. Since classes are heap allocated, you can allocate an instance of the class and grab a pointer to the associative array. class HeapAA { int[string] a; } int[string]*b = (new HeapAA).a;
Purity not enforced for default arguments?
The following code fails to compile because unpredictableSeed is impure: void main() { foreach(i; 0..10) writeln(pureRandom); } pure uint pureRandom() { auto r = Random(unpredictableSeed); return r.front; } However, make unpredictableSeed a default argument, wrap the call in another pure function, and it compiles: void main() { foreach(i; 0..10) writeln(pureRandom2); } pure uint pureRandom2() { return pureRandom; } pure uint pureRandom(uint seed = unpredictableSeed) { auto r = Random(seed); return r.front; } I'm inclined to believe this is a bug. While pureRandom could be considered weakly pure, pureRandom2 has no arguments so it should be strongly pure. Yet, it yields a different value on every call.
Re: Purity not enforced for default arguments?
On Tuesday, 10 March 2015 at 22:00:29 UTC, safety0ff wrote: On Tuesday, 10 March 2015 at 21:56:39 UTC, Xinok wrote: I'm inclined to believe this is a bug. https://issues.dlang.org/show_bug.cgi?id=11048 Thanks for the link, and I didn't mean to post this in D.learn. .
Re: Sorted Array Wrapper Range
On Wednesday, 3 December 2014 at 21:02:05 UTC, Nordlöw wrote: Have anybody written a generic automatically sorted range wrapper for RandomAccessRanges? I guess http://dlang.org/library/std/range/assumeSorted.html should play a key role. I see two typical variants: - Direct: Always sorts on write() and modify() - Lazy: Sorts lazily on read() read() of course uses binarySearch There was a relevant discussion about a month ago here: http://forum.dlang.org/thread/uhfpppdslxdghycon...@forum.dlang.org Otherwise, there's RedBlackTree, but I'm not aware of anything that works over any random-access range.
Re: How to initialise array of ubytes?
On Saturday, 29 November 2014 at 20:47:09 UTC, Paul wrote: On Saturday, 29 November 2014 at 20:22:40 UTC, bearophile wrote: This works: enum MAPSIZE = 3; void main() { ubyte[MAPSIZE][MAPSIZE] map2 = 1; } This doesn't work: enum MAPSIZE = 3; ubyte[MAPSIZE][MAPSIZE] map1 = ubyte(1); void main() {} Why isn't this working? I'm afraid I don't know. I would guess it's something to do with trying to initialise the array in the global scope but you've also changed the expression in the non-working example. I don't have access to my machine at present so I can't experiment! More generally, it's because one is static (as in global / thread-local) and the other is not. Take the working example, put static in front of the declaration, and you'll get the same error. There are different rules regarding the initialization of static and non-static variables. My guess, they're implemented as separate features in the compiler, so when vector operations were introduced, nobody thought to implement this feature as a way to initialize static arrays as well.
Why the DMD Backend?
Given that we have GDC with the GCC backend and LDC with the LLVM backend, what are the benefits of keeping the DMD compiler backend? It seems to me that GCC and LLVM are far more developed and better supported by their respective communities. They have superior optimizers and are better equipped for migrating D to new platforms. On the other hand, from what I gather, there's lots of work to be done on DMD on improving support for x64 Windows and ARM. It's a genuine question, which is why I posted this to D.learn. I don't follow development on the backend and overall I'm unfamiliar with compilers, so I'm not sure what the benefits are of the D community continuing to maintain it's own backend.
Re: More flexible sorted ranges?
On Sunday, 2 November 2014 at 17:21:04 UTC, Ola Fosheim Grøstad wrote: On Sunday, 2 November 2014 at 16:59:30 UTC, bearophile wrote: Ola Fosheim Grøstad: Shouldn't sorted range maintain the invariant automatically in order to remain typesafe? Yes, of course. If SortedRange is fixed, please also switch the names of upperBound and lowerBound… They are currently wrong. An upperBound on something should return the values lower than it and a lowerBound should return values larger… (C++ got it right). D got it right. C++ returns an iterator which can be a bit confusing. D returns a slice so it's meaning is much clearer. https://en.wikipedia.org/wiki/Upper_and_lower_bounds http://www.cplusplus.com/reference/algorithm/upper_bound/
Re: More flexible sorted ranges?
On Sunday, 2 November 2014 at 15:13:37 UTC, bearophile wrote: I have often arrays that are sorted, and sometimes I'd like to append items to them. So I'd like to write something like: SortedRange!(Foo[], q{ a.x b.x }) data; data ~= Foo(5); immutable n = data.upperBound(Foo(2)).length; This means having an array of Foos as sorted range, and appending an item to it keeping the sorting invariant (so in non-release mode the append verifies the array is empty or the last two items satisfy the sorting invariant), and this allows me to call functions like upperBound any time I want on 'data' without using any unsafe and unclean assumeSorted. Is this possible and a good idea to do? Bye, bearophile My concern is that SortedRange only accepts a range which is random-access and limits its functionality to those primitives. Concatenation is not required for random-access ranges, so should we expect SortedRange to overload this operator?
Re: More flexible sorted ranges?
On Sunday, 2 November 2014 at 20:06:51 UTC, Ola Fosheim Grøstad wrote: On Sunday, 2 November 2014 at 19:54:38 UTC, Xinok wrote: D got it right. C++ returns an iterator which can be a bit confusing. D returns a slice so it's meaning is much clearer. No, according to docs D has defined the lower bound to be the negation of the lower bound… Sorry, you're right, it's not an upper bound. I read that definition a few times over and still got it wrong. O_o In terms of what to call it, perhaps what you're looking for is upper set? https://en.wikipedia.org/wiki/Upper_set
Re: More flexible sorted ranges?
On Sunday, 2 November 2014 at 20:19:12 UTC, bearophile wrote: Xinok: My concern is that SortedRange only accepts a range which is random-access and limits its functionality to those primitives. Concatenation is not required for random-access ranges, so should we expect SortedRange to overload this operator? I understand, that's why I am asking this here... I think the desire to keep a sorted range around and grow it keeping its invariant is a common enough need for my code. Currently I keep an array then I use assumeSorted + upperBound, but this is not safe nor nice. Perhaps sorted ranges should become more transparent in Phobos. There are other invariants beside sortness that can be useful to carry around, like set-ness (every item is unique inside this collection) and few more. Bye, bearophile I take back my original argument. As of 2.066, the requirements for SortedRange have been relaxed so it now accepts input ranges. The documentation needs to be updated to reflect this change. Still, I'm not comfortable to adding concatenation to SortedRange. I would prefer named functions which append / prepend elements with the guarantee that it preserves the invariant. In general, I don't feel that SortedRange is an ideal solution anyways. Wrapping ranges in a struct adds too much overhead and we can't extend the functionality of it. Would it be possible to replace SortedRange with a @sorted attribute or something?
Trouble reproducing compilation error
I'm currently receiving several errors when trying to compile this code with DMD 2.066 (beginning with RC1): https://github.com/Xinok/XSort The compiler throws an error because it's unable to deduce a type for the predicate in a few places. This repository compiles just fine in DMD 2.065 and earlier (more specifically, 2.066 beta 5 and earlier). I'm very certain that this is a bug given that I never experienced this issue before. However, I'm finding it impossible to reproduce the bug so I can file a bug report. I'm not sure what exactly is causing it or if there's something specific in the context of this code that's triggering it. The only thing that I can deduce is that, in each case, an instance variable is being compared to an array element, e.g.: int[] arr = [10, 20, 30]; int value = arr[0]; pred(value, arr[1]); // Instance variable compared to array element This one is stumping me and I could use some help in tracking down this bug.
Re: Trouble reproducing compilation error
This is the full compiler output: combsort.d(90): Error: template D main.pred cannot deduce function from argument types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(81): Error: template instance combsort.combSortLinear!(pred, uint[]) error instantiating combsort.d(135): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) combsort.d(151): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(82): Error: template instance combsort.combSortGallop!(pred, uint[]) error instantiating forwardsort.d(218): Error: template D main.pred cannot deduce function from argu ment types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) forwardsort.d(138): Error: template D main.pred cannot deduce function from argu ment types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) forwardsort.d(52): Error: template D main.pred cannot deduce function from argum ent types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(84): Error: template instance forwardsort.forwardSort!(pred, uint[]) error instantiating heapsort.d(119): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) heapsort.d(102): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(99): Error: template instance heapsort.heapSort!(pred, false, uint[] ) error instantiating heapsort.d(119): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) heapsort.d(102): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(101): Error: template instance heapsort.heapSort!(pred, true, uint[] ) error instantiating heapsort.d(221): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(103): Error: template instance heapsort.bottomUpHeapSort!(pred, fals e, uint[]) error instantiating heapsort.d(221): Error: template D main.pred cannot deduce function from argumen t types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(104): Error: template instance heapsort.bottomUpHeapSort!(pred, true , uint[]) error instantiating insertionsort.d(45): Error: template D main.pred cannot deduce function from arg ument types !()(uint, uint), candidates are: benchsort.d(37):benchsort.main.pred(T)(T a, T b) benchsort.d(108): Error: template instance insertionsort.insertionSort!(pred, ui nt[]) error instantiating