Re: Looking for a language to hang my hat on.
On Monday, 16 November 2015 at 22:39:17 UTC, Dan wrote: I have been lurking on this site over the past few weeks trying to decide when (and if) to make the transition. Can anyone here who has already made that transition tell me how smoothly it went? Any major unexpected problems? Advice? thanks! Dan What do you plan to do with D? Learn it so you can use it for personal projects? Write large apps for a business? Use it in a job? The answer depends on how you'll use it. Personally, I don't think there is a reason to transition. Instead, you should learn D and then use it when you are ready.
Re: How to use readText to read utf16 file?
On Tuesday, 17 November 2015 at 02:40:14 UTC, Domain wrote: How to use readText to read utf16 file? Or other encoding file. Here's a helpful resource when working with text files in D. http://nomad.so/2015/09/working-with-files-in-the-d-programming-language/
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 11:58:22 UTC, Chris wrote: Sorry that should be: @property void popFront() { r = r[1..$]; cnt++; }
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 12:41:45 UTC, Chris wrote: On Tuesday, 17 November 2015 at 12:22:22 UTC, Marc Schütz wrote: In any case, I'd suggest you fix your opIndex(), except if there's a really good reason it is as it is. I see. Thanks for the explanation. What would be the easiest fix for this example? Do you actually need the opIndex()? If not, just remove it.
Re: Looking for a language to hang my hat on.
On Tuesday, 17 November 2015 at 00:33:44 UTC, Chris Wright wrote: This might change, but that's a gamble, and not one I'd take. For projects where you need specific libraries to exist already, D probably won't serve your needs. (It's definitely easier with C++ interop, but you'd still have to write bindings. htod doesn't exactly work on Linux.) Does anyone still use htod? I thought dstep was the tool being used to generate bindings. It depends on what OP plans to do. C interop is generally very easy, so anything available in C is also available in D, but it depends on how much of the glue code needs to be written. It has never been a big deal for me. The bigger problem is figuring out what the C library does than how to interface with it. One additional thing I've learned is that other languages might have large numbers of libraries "available" but a lot of it is low quality, undocumented/poorly documented stuff. The ability to easily write C bindings is in many cases preferable to complicated C interop but existing libraries.
Re: Invalid foreach aggregate
I've checked several options now and it doesn't work. Here (http://dlang.org/statement.html#foreach-with-ranges) it is stated that it suffices to have range primitives, if opApply doesn't exist. My code worked up to 2.068.0, with the introduction of 2.068.1 it failed. I wonder why that is. I have empty, front and popFront in my range which is a struct, and it used to work.
Re: Invalid foreach aggregate
On Monday, 16 November 2015 at 18:18:51 UTC, Chris wrote: On Monday, 16 November 2015 at 17:57:53 UTC, opla wrote: On Monday, 16 November 2015 at 16:55:29 UTC, Chris wrote: On Monday, 16 November 2015 at 16:49:19 UTC, Marc Schütz wrote: On Monday, 16 November 2015 at 16:44:27 UTC, Chris wrote: Updating my code from 2.067.1 to 2.069.1 (I skipped 2.068, because I was too busy). I get this error: invalid foreach aggregate, define opApply(), range primitives, or use .tupleof for code like foreach (ref it; myArray.doSomething) {} Probably not the best idea anyway. What's the best fix for this? Thanks. Well, what does `doSomething` return? It returns a range that modifies individual items in myArray, i.e. it assigns values to fields in each item of the array. have you... tried without ref tried by adding a pair of parens after doSomething ? tried std.algorithm.each or map on doSomething ? checked the primitives ? checked that isInputRange!(ReturnType!doSomething) == true? I think ref is necessary, else the items are not changed. I will try the other options tomorrow (Tuesday). Thanks. I wonder was the change overdue (and I got away with it till 2.068.1) or is it a new policy due to changes in D? That really depends on the details, that's why I asked. It could be a regression, or it could be that the compiler now does stricter checking than before, and your implementation wasn't completely correct, or it could be a bug in Phobos if you use that to create the range. If you can post a minimal example that works in 2.067.1, but doesn't with the current version, I can try to find the change that broke it.
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 11:58:22 UTC, Chris wrote: I did just that and I could find the culprit. It's opIndex(). It works up until 2.068.0, with 2.068.1 I already get this error: "primitives.d(7): Error: invalid foreach aggregate doSomething(items).opIndex()" @property size_t opIndex() { return cnt; } Ok, that's a strange implementation of opIndex(). Usually, a parameter-less opIndex() is supposed to return a slice into the full range, but yours returns a size_t, which of course can't be iterated over. The change that made this stop working is: https://github.com/D-Programming-Language/dmd/pull/4948 This contains, among others a fix for issue 14625 "opIndex() doesn't work on foreach container iteration": https://issues.dlang.org/show_bug.cgi?id=14625 This allows to iterate directly over containers, without needing to slice them first. I guess it's a bit too eager, because if the object is already iterable without slicing (as in your example), it could just do that. On the other hand, it's a corner case, and it might actually be preferable to slice always, if the iterable supports it... In any case, I'd suggest you fix your opIndex(), except if there's a really good reason it is as it is.
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 12:22:22 UTC, Marc Schütz wrote: Ok, that's a strange implementation of opIndex(). Usually, a parameter-less opIndex() is supposed to return a slice into the full range, but yours returns a size_t, which of course can't be iterated over. The change that made this stop working is: https://github.com/D-Programming-Language/dmd/pull/4948 This contains, among others a fix for issue 14625 "opIndex() doesn't work on foreach container iteration": https://issues.dlang.org/show_bug.cgi?id=14625 This allows to iterate directly over containers, without needing to slice them first. I guess it's a bit too eager, because if the object is already iterable without slicing (as in your example), it could just do that. On the other hand, it's a corner case, and it might actually be preferable to slice always, if the iterable supports it... In any case, I'd suggest you fix your opIndex(), except if there's a really good reason it is as it is. I see. Thanks for the explanation. What would be the easiest fix for this example?
Re: Filtering a tuple of containers with indices
On 17.11.2015 15:32, maik klein wrote: template tupIndexToRange(alias Tup, Indices...){ [snip] I don't quite understand how that code is supposed to work. Maybe there's just some detail missing, but it could also be that your approach can't work. This is roughly what I want to achieve alias Integrals = AliasSeq!(Array!int, Array!float, Array!double); Integrals integrals; integrals[0].insertBack(1); integrals[1].insertBack(2); integrals[2].insertBack(3); auto range = zip(tuple(integrals[0][],integrals[1][]).expand); writeln(range); foreach(e;range){ writeln("element: ",e); } But instead of "auto range = zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to be generic "auto range = zip(tupIndexToRange!(integrals, AliasSeq!(0, 1)).expand);" I think the problem can be split up into two independent tasks: 1) Select fields of a tuple by indices (to drop `integrals[3]`). 2) A "map" function for tuples (to apply `[]` to the selected arrays). Here are two quick implementations of those applied to your problem: template selectFromTuple(indices ...) { auto selectFromTuple(Types...)(Types values) { import std.typecons: tuple, Tuple; static if (indices.length == 0) return Tuple!()(); else { enum headIndex = indices[0]; auto tail = .selectFromTuple!(indices[1 .. $])(values); return tuple(values[headIndex], tail.expand); } } } auto mapTuple(alias op, Types ...)(Types values) { import std.meta: staticMap; import std.typecons: tuple; alias ResultType(T) = typeof(op(T.init)); alias ResultTypes = staticMap!(ResultType, Types); ResultTypes results; foreach (i, v; values) results[i] = op(v); return tuple(results); } void main() { import std.container.array; import std.meta: AliasSeq; import std.range: zip; import std.stdio: writeln; alias Integrals = AliasSeq!(Array!int, Array!float, Array!double); Integrals integrals; integrals[0].insertBack(1); integrals[1].insertBack(2); integrals[2].insertBack(3); auto range = integrals .selectFromTuple!(0, 1).expand .mapTuple!(a => a[]).expand .zip; writeln(range); foreach(e;range){ writeln("element: ",e); } } That looks a lot like range based programming, which makes me think that there could be a way to use actual range algorithms from std.algorithm for this. But I don't see how.
Re: How to use readText to read utf16 file?
On Tuesday, 17 November 2015 at 05:37:55 UTC, Domain wrote: Thank you! Now another question: how to handle endianness? If your file follow a file format: the endianness should be defined there. else it's a random text file: either it will have a BOM with endianness, or you will have to guess.
Re: Looking for a language to hang my hat on.
Thanks everyone for taking the time to respond! @Lobo, Start using D now. It's not all or nothing so you don't have to give up on C++. I have several projects that contain both C++ and D intermixed. Using both does seem like a good way to transition. I could combine the strengths of D with the strengths of c++. I have never mixed two programming languages in one project, all have contained one language exclusively. This is another bridge to cross. D will make you a better C++ programmer, but especially C++ template programming. D metaprogramming is so easy to read, write and understand compared to C++ and many of the patterns still apply when you're standing knee deep in C++it. I use c++ templates extensively, and if D offers a better solution that is fantastic. @Chris Wright, Your largest problem in the short term is documentation quality. This concerns me since it makes it very difficult for people trying to learn the language. I don't need that additional frustration. Your largest problem in the long run will be libraries. Also concerning, but if I can combine the two languages somehow as lobo suggested, there may be a solution (just need to figure out how and how difficult that is). ...but you'd still have to write bindings. htod doesn't exactly work on Linux. I am not exactly sure what that means, which is probably not a good sign. --- @Russel Windmer But doesn't code::blocks just interface with the compiler? I (naively?) thought I could just install the compiler and point code::blocks to that compiler. --- @Bachmeier What do you plan to do with D? Good point, I did not make that clear. Right now I just want to use it for personal projects, but someday I hope to take it further. Personally, I don't think there is a reason to transition. Instead, you should learn D and then use it when you are ready. That is troubling, but reasons to transition must exist or the language would not exist, right? I find that if I "learn" a language I forget it unless I actually start using it, at least for a short while. January 2016 is when I should have time to experiment with D. I will attempt to install the language in Linux and kick the tires for a while. If I continuously stumble into insurmountable barriers, the experiment will end.
Filtering a tuple of containers with indices
The question is also posted on https://stackoverflow.com/questions/33757981/filtering-a-tuple-of-containers-with-indicies template tupIndexToRange(alias Tup, Indices...){ import std.meta; static if(Indicies.length == 0){ alias tupIndexToRange = AliasSeq!(); } else{ alias tupIndexToRange = AliasSeq!(Tup[ Indices[0] ][], tupIndexToRange!(Tup,Indices[1..$])); } } void main{ alias Integrals = AliasSeq!(Array!int, Array!float, Array!double); Integrals integrals; alias IntegralRange = tupIndexToRange!(integrals,0,1); } void main{ alias Integrals = AliasSeq!(Array!int, Array!float, Array!double); Integrals integrals; alias IntegralRange = tupIndexToRange!(integrals,0,1); } I want to achieve something like this auto range = zip(tupIndexToRange!(integrals,0,1)); I think the main problem is that Tup[ Indicies[0] ] doesn't work, to me it should have expanded to this AliasSeq!(itegrals[0][],integrals[1][]); This is roughly what I want to achieve alias Integrals = AliasSeq!(Array!int, Array!float, Array!double); Integrals integrals; integrals[0].insertBack(1); integrals[1].insertBack(2); integrals[2].insertBack(3); auto range = zip(tuple(integrals[0][],integrals[1][]).expand); writeln(range); foreach(e;range){ writeln("element: ",e); } But instead of "auto range = zip(tuple(integrals[0][],integrals[1][]).expand);" I want it to be generic "auto range = zip(tupIndexToRange!(integrals, AliasSeq!(0, 1)).expand);" Maybe I need use mixins?
Re: dataframe implementations
I looked through the dataframe code and a couple of comments... I had thought perhaps an app could read in the header info and type info from hdf5, and generate D struct definitions with column headers as symbol names. That would enable faster processing than with the associative arrays, as well as support the auto-completion that would be helpful in writing expressions. The csv type info for columns could be inferred, or else stated in the reader call, as done as an option in julia. In both cases the column names would have to be valid symbol names for this to work. I believe Julia also expects this, or else does some conversion on your column names to make them valid symbols. I think the D csv processing would also need to check if the The jupyter interactive environment supports python pandas and Julia dataframe column names in the autocompletion, and so I think the D debugging environment would need to provide similar capability if it is to be considered as a fast-recompile substitute for interactive dataframe exploration. It seems to me that your particular examples of stock data would eventually need to handle missing data, as supported in Julia dataframes and python pandas. They both provide ways to drop or fill missing values. Did you want to support that?
Re: Looking for a language to hang my hat on.
On Tuesday, 17 November 2015 at 14:21:27 UTC, Dan wrote: Personally, I don't think there is a reason to transition. Instead, you should learn D and then use it when you are ready. That is troubling, but reasons to transition must exist or the language would not exist, right? I find that if I "learn" a language I forget it unless I actually start using it, at least for a short while. January 2016 is when I should have time to experiment with D. I will attempt to install the language in Linux and kick the tires for a while. If I continuously stumble into insurmountable barriers, the experiment will end. I meant there is no reason to abandon C++ in favor of D. The lowest cost way to get started with D is to write some functions in D and call them from C++. I personally don't like the term "transition" because it implies significant cost.
Re: Invalid foreach aggregate
On Tuesday, 17 November 2015 at 11:26:19 UTC, Marc Schütz wrote: That really depends on the details, that's why I asked. It could be a regression, or it could be that the compiler now does stricter checking than before, and your implementation wasn't completely correct, or it could be a bug in Phobos if you use that to create the range. If you can post a minimal example that works in 2.067.1, but doesn't with the current version, I can try to find the change that broke it. I did just that and I could find the culprit. It's opIndex(). It works up until 2.068.0, with 2.068.1 I already get this error: "primitives.d(7): Error: invalid foreach aggregate doSomething(items).opIndex()" Here's the example: = import std.stdio : writeln; import std.range.primitives; void main() { string[] items = ["a", "b", "c"]; foreach (ref it; items.doSomething()) { writeln(it); } } auto doSomething(InputRange)(ref InputRange r) { struct DoSomething { private { InputRange r; size_t cnt; } this(InputRange r) { this.r = r; } @property bool empty() { return r.length == 0; } @property auto front() { return r[0]; } @property void popFront() { r = r[1..$]; } @property size_t length() const { return r.length; } @property size_t opIndex() { return cnt; } @property auto save() const { return this; } } return DoSomething(r); }
Re: Looking for a language to hang my hat on.
On Tue, 17 Nov 2015 10:53:04 +, bachmeier wrote: > On Tuesday, 17 November 2015 at 00:33:44 UTC, Chris Wright wrote: >> This might change, but that's a gamble, and not one I'd take. >> For projects where you need specific libraries to exist already, D >> probably won't serve your needs. (It's definitely easier with C++ >> interop, but you'd still have to write bindings. htod doesn't exactly >> work on Linux.) > > Does anyone still use htod? I thought dstep was the tool being used to > generate bindings. dstep doesn't work out of the box. A simple `dub run dstep` results in compilation errors.
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; }
compatible types for chains of different lengths
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. A short example: $ cat chain.d 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 = (args.length > 1) ? chain(x1, x2) : chain(x1); auto chain2 = (args.length > 1) ? chain(x1, x2, x3) : chain(x1, x2); chain1.joiner(", ").writeln; chain2.joiner(", ").writeln; } $ dmd chain.d chain.d(10): Error: incompatible types for ((chain(x1, x2)) : (chain(x1))): 'Result' and 'string[]' chain.d(11): Error: incompatible types for ((chain(x1, x2, x3)) : (chain(x1, x2))): 'Result' and 'Result' Is there a different way to do this? --Jon
Re: Filtering a tuple of containers with indices
On Tuesday, 17 November 2015 at 15:48:10 UTC, anonymous wrote: On 17.11.2015 15:32, maik klein wrote: [...] [snip] I don't quite understand how that code is supposed to work. Maybe there's just some detail missing, but it could also be that your approach can't work. [...] Thanks but I have one question. .selectFromTuple!(0, 1).expand Does this result in a copy? I avoided doing it like this because I was worried that I would copy every array. But I also don't fully understand when D will copy. Also doing foreach(e;range){ e[0] = 10; e[1] = 10.0f; writeln("element: ",e); } foreach(e;range){ writeln("element: ",e); } doesn't mutate the range at all.
Re: Filtering a tuple of containers with indices
On 17.11.2015 20:46, maik klein wrote: .selectFromTuple!(0, 1).expand Does this result in a copy? I avoided doing it like this because I was worried that I would copy every array. But I also don't fully understand when D will copy. Yes and no. It copies the Array structs, but it does not copy the elements of the arrays. If I remember correctly, std.container.Array uses reference counting, and copying them should be cheap. By the way, do you have a good reason to go with Array!int rather than int[]? They're similar, but the builtin int[] may be easier to handle. Also doing foreach(e;range){ e[0] = 10; e[1] = 10.0f; writeln("element: ",e); } foreach(e;range){ writeln("element: ",e); } doesn't mutate the range at all. You need to mark the `e` as `ref`: `foreach(ref e; range)`. Otherwise, it's a copy of the element, and any changes to it are forgotten at the end of the iteration. But even with `ref` it doesn't work. Seems to be a bug in or a limitation of `zip`. Works with `lockstep`: auto ranges = integrals .selectFromTuple!(0, 1).expand .mapTuple!(a => a[]).expand; auto range = ranges.zip; import std.range: lockstep; foreach(ref e0, ref e1; lockstep(ranges)){ e0 = 10; e1 = 10.0f; } foreach(e;range){ writeln("element: ",e); }
Re: opEquals default behaviour - poorly documented or am I missing something?
On 11/17/15 3:25 PM, user123ABCabc wrote: On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote: if (typeid(a) == typeid(b)) return a.opEquals(b); Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ? No, those are immutable stored in the data segment. Fetching them costs only doing the fetch of the class info pointer. -Steve
Re: opEquals default behaviour - poorly documented or am I missing something?
On 11/17/2015 12:40 AM, MichaelZ wrote: > In http://dlang.org/operatoroverloading.html#eqcmp it is stated that > > "If opEquals is not specified, the compiler provides a default version > that does member-wise comparison." > > However, doesn't this only apply to structs, and not objects? Correct. The behavior for class objects is the following algorithm on the same page: http://dlang.org/operatoroverloading.html#equals This one: bool opEquals(Object a, Object b) { if (a is b) return true; if (a is null || b is null) return false; if (typeid(a) == typeid(b)) return a.opEquals(b); return a.opEquals(b) && b.opEquals(a); } Ali
Re: opEquals default behaviour - poorly documented or am I missing something?
On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote: if (typeid(a) == typeid(b)) return a.opEquals(b); Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ? But usually when comparing objects one rather cares about the reference itself, so a comparison of the two heap addresses is enough in this case. (meaning same or not same instance, regardless of the their members values).
Re: compatible types for chains of different lengths
On Tuesday, 17 November 2015 at 23:22:58 UTC, Brad Anderson wrote: One solution: [snip] Thanks for the quick response. Extending your example, here's another style that works and may be nicer in some cases. 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 y1 = (args.length > 1) ? x1 : []; auto y2 = (args.length > 2) ? x2 : []; auto y3 = (args.length > 3) ? x3 : []; chain(y1, y2, y3).joiner(", ").writeln; }
opEquals default behaviour - poorly documented or am I missing something?
In http://dlang.org/operatoroverloading.html#eqcmp it is stated that "If opEquals is not specified, the compiler provides a default version that does member-wise comparison." However, doesn't this only apply to structs, and not objects? The default behaviour of opEquals for objects seems to be "is". A few paragraphs later, in http://dlang.org/operatoroverloading.html#compare, the description of the default version is repeated: "" If overriding Object.opCmp() for classes, the class member function signature should look like: ... If structs declare an opCmp member function, it should have the following form: ... Note that opCmp is only used for the inequality operators; expressions like a == b always uses opEquals. **If opCmp is defined but opEquals isn't, the compiler will supply a default version of opEquals that performs member-wise comparison.** "" Even here, the fact that the described default opEquals behaviour appears to only apply to structs is far from clear. Or am I missing something that should be obvious? Thanks, -- MichaelZ
Re: Looking for a language to hang my hat on.
On Mon, 2015-11-16 at 22:39 +, Dan via Digitalmars-d-learn wrote: > […] > My platform of choice is 64-bit Fedora using Code::Blocks (yes, I > use an IDE as a crutch). It seems that D supports this combo. Last time I looked at Code::Blocks it couldn't do a dark theme, and the D support was for an ancient form of D. It would be good if we could get Kingsley's IntelliJ IDEA D plugin into CLion. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part