Scalar + array operations
When working on my current project (writing a numerical simulation code) I ran into the following issue when trying to multiply a vector (represented by a fixed-length array) by a scalar: import std.stdio; void main() { int ifoo = 2; int[3] ibar = 1; double dfoo = 2.0; double[3] dbar = 1.0; dfoo = ifoo * dfoo; // Scalar int * scalar double -- OK writeln(dfoo); dfoo = dfoo * dfoo; // Scalar double * scalar double -- OK writeln(dfoo); dbar = dfoo * dbar[];// Scalar double * array of double -- OK writeln(dbar); ibar = ifoo * ibar[];// Scalar int * array of int -- OK writeln(ibar); dbar = ifoo * dbar[];// Scalar int * array of double -- OK writeln(dbar); // dbar = dfoo * ibar[]; // Scalar double * array of int -- FAIL // writeln(dbar); } I would have expected the last case to work as well, but I get testarr.d(20): Error: incompatible types for ((dfoo) * (ibar[])): 'double' and 'int[]' Is this by design? It was very surprising to me, especially since all other combinations do seem to work. Kind regards, Stefan Frijters
Re: Scalar + array operations
Stefan Frijters: Is this by design? It was very surprising to me, especially since all other combinations do seem to work. I don't know if this situation is by design. At first sights it seems a limitation that could be removed. Bye, bearophile
Re: Scalar + array operations
On Wednesday, 21 May 2014 at 11:45:57 UTC, Stefan Frijters wrote: When working on my current project (writing a numerical simulation code) I ran into the following issue when trying to multiply a vector (represented by a fixed-length array) by a scalar: import std.stdio; void main() { int ifoo = 2; int[3] ibar = 1; double dfoo = 2.0; double[3] dbar = 1.0; dfoo = ifoo * dfoo; // Scalar int * scalar double -- OK writeln(dfoo); dfoo = dfoo * dfoo; // Scalar double * scalar double -- OK writeln(dfoo); dbar = dfoo * dbar[];// Scalar double * array of double -- OK writeln(dbar); ibar = ifoo * ibar[];// Scalar int * array of int -- OK writeln(ibar); dbar = ifoo * dbar[];// Scalar int * array of double -- OK writeln(dbar); // dbar = dfoo * ibar[]; // Scalar double * array of int -- FAIL // writeln(dbar); } I would have expected the last case to work as well, but I get testarr.d(20): Error: incompatible types for ((dfoo) * (ibar[])): 'double' and 'int[]' Is this by design? It was very surprising to me, especially since all other combinations do seem to work. Kind regards, Stefan Frijters Please file a bug, there's no reason for that not to work, it just needs to be implemented properly.
Re: Scalar + array operations
On Wednesday, 21 May 2014 at 13:52:47 UTC, John Colvin wrote: Please file a bug, there's no reason for that not to work, it just needs to be implemented properly. Ok, thanks for confirming. Filed as https://issues.dlang.org/show_bug.cgi?id=12780 .
Re: Scalar + array operations
On Wednesday, 21 May 2014 at 13:52:47 UTC, John Colvin wrote: On Wednesday, 21 May 2014 at 11:45:57 UTC, Stefan Frijters wrote: I would have expected the last case to work as well, but I get testarr.d(20): Error: incompatible types for ((dfoo) * (ibar[])): 'double' and 'int[]' Is this by design? It was very surprising to me, especially since all other combinations do seem to work. Kind regards, Stefan Frijters Please file a bug, there's no reason for that not to work, it just needs to be implemented properly. To me, it just feels reasonable that it is not allowed. What should be the correct type of the result? int[]? I thought double to int conversion was not allowed unless you explicitly asked for it.
Re: Scalar + array operations
On Wednesday, 21 May 2014 at 17:07:27 UTC, Francesco Cattoglio wrote: On Wednesday, 21 May 2014 at 13:52:47 UTC, John Colvin wrote: On Wednesday, 21 May 2014 at 11:45:57 UTC, Stefan Frijters wrote: I would have expected the last case to work as well, but I get testarr.d(20): Error: incompatible types for ((dfoo) * (ibar[])): 'double' and 'int[]' Is this by design? It was very surprising to me, especially since all other combinations do seem to work. Kind regards, Stefan Frijters Please file a bug, there's no reason for that not to work, it just needs to be implemented properly. To me, it just feels reasonable that it is not allowed. What should be the correct type of the result? int[]? I thought double to int conversion was not allowed unless you explicitly asked for it. No, I expected and desired an array of doubles, implicitly converting the array of ints to doubles.
Re: std.concurrency bug?
On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote: > On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn > wrote: >> On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: >>> Is it a bug that an immutable struct cannot be sent to a thread? (It >>> compiles without problem if I make all elements mutable.) Further reduced: import std.concurrency; struct S { immutable int i; } void foo() {} void main() { auto f = spawn(&foo); auto s = S(); f.send(s); } I think this is a known issue with immutable and Variant, which std.concurrency uses for unknown messages. This looks related: https://issues.dlang.org/show_bug.cgi?id=5538 Ali
Re: std.concurrency bug?
On Wednesday, May 21, 2014 01:19:32 PM Ali Çehreli via Digitalmars-d-learn wrote: > On 05/20/2014 05:24 PM, Charles Hixson via Digitalmars-d-learn wrote: > > On Tuesday, May 20, 2014 11:42:48 AM Ali Çehreli via Digitalmars-d-learn > > > > wrote: > >> On 05/20/2014 11:38 AM, Charles Hixson via Digitalmars-d-learn wrote: > >>> Is it a bug that an immutable struct cannot be sent to a thread? (It > >>> compiles without problem if I make all elements mutable.) > > Further reduced: > > import std.concurrency; > > struct S > { > immutable int i; > } > > void foo() > {} > > void main() > { > auto f = spawn(&foo); > > auto s = S(); > f.send(s); > } > > I think this is a known issue with immutable and Variant, which > std.concurrency uses for unknown messages. This looks related: > >https://issues.dlang.org/show_bug.cgi?id=5538 > > Ali Thanks. Fortunately, I don't really need for messages to be immutable, I just thought it would be safer (as in avoiding the possibility of making a mistake). They're stucts, and I never pass a pointer, just the struct. Being immutable would allow me to guarantee that certain logic errors couldn't be committed is all.
DLang Front Page Code Example
I was looking at this code the other day and thought to my self "This is terrible D" in the order of the C hello world with no error handling and returning a junk stack value. I am a reasonably experienced C++ programmer but still a newbie at D. However, between the ideals of reusable code and no raw loops I felt there must be a better way. https://www.youtube.com/watch?v=cQkBOCo8UrE http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning So I tried rewriting the example on the dlang.org home page and came up with the following. import std.algorithm, std.exception, std.stdio; double average(T)(T range) { enforce(!range.empty, "No inputs"); auto totals = range.map!(a => tuple(1.0, cast(double)(a))).reduce!((a, b) => tuple(a[0] + b[0], a[1] + b[1])); return totals[1] / totals[0]; } void main() { writeln("Average line length: ", stdin.byLine.map!(a => a.length).average); } In doing so I ran into a few issues. - Average or mean did not seem to already exist in algorithm or numeric. - I could not think of an easy way to add component wise binaryOp to a Tuple. - Tried using static array instead of tuple but could not work out how to crate a static array as the result of a lambda. - Using dynamic array caused a compile issue and presumably would have had terrible heap garbage. I am not necessarily saying we should replace the existing example but was curious what other people thought.