Re: Why does sum not work in static arrays?
On Sun, Oct 11, 2020 at 01:26:13PM +, Alaindevos via Digitalmars-d-learn wrote: > Sidenote, sort also not works with static arrays. Just slice it with []. T -- I think the conspiracy theorists are out to get us...
Re: Why does sum not work in static arrays?
Sidenote, sort also not works with static arrays.
Re: Why does sum not work in static arrays?
On Sunday, 6 December 2015 at 12:27:49 UTC, cym13 wrote: On Sunday, 6 December 2015 at 12:23:05 UTC, Tim K. wrote: Hi! I have the following code: int main(string[] argv) { import std.algorithm: sum; import std.stdio: writeln; uint[3] a1 = [1, 2, 3]; uint[] a2; for (int i = 1; i <= 3; ++i) a2 ~= i; writeln("a1: ", sum(a1)); writeln("a2: ", sum(a2)); return 0; } This throws the error: dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(3916): std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))) /usr/include/dmd/phobos/std/algorithm/iteration.d(3927): std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front))) So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays? Regards So that you do not shoot yourself in the foot too easily. A static array is a value type so it is passed by value to functions. If you pass a 1M array to a function... well, I guesse you don't want to do that. Can the template func `sum()` be made to take `ref` of a static array? The solution is to slice it: a1[].sum; That way you avoid the problem. While I understand the explanation of the current behavior, and the work-around, this inconstancy of making func calls means either the library, or the language leaves something to be desired: i.e dynamic array and static array cannot be used interchangeably: (sure I'm not talking about array decl / allocation, the user have to take different actions) I'm talking about a simple function call to calc the sum of the array. ``` sum(static_array[]); // v.s. sum(dynamic_array); ``` For example, if the user first decl a static array for fast prototyping, and later changed mind to use dynamic array, then s/he need to change the call all over the places. (I hope you are not telling me, every time people should use: ``` array_func(any_array[]); ``` is the correct D-idiom to use array in a func call)
Re: Why does choose not work here
On Thursday, 1 August 2019 at 21:26:10 UTC, Matt wrote: Anyone have any other thoughts? I tried to simplify your example a little bit: import std.stdio; import std.range; import std.algorithm; auto myFilter(R1, R2)(R1 a, R2 b) { return a.filter!(c => c==b.front); } struct A { int[] starts; auto intervalRange() @property { return starts; } } auto uniqIntervalsA(A primary, A* previous) @property { return choose(previous is null, primary.intervalRange, primary.intervalRange.filter!(a => a==previous.intervalRange.front)); } auto uniqIntervalsB(A primary, A* previous) @property { return choose(previous is null, primary.intervalRange, primary.intervalRange.myFilter(previous.intervalRange)); } unittest { auto a1 = A([1]); writeln(uniqIntervalsA(a1,)); writeln(uniqIntervalsA(a1,null)); writeln(uniqIntervalsB(a1,)); writeln(uniqIntervalsB(a1,null)); } The strange thing is, that even if you replace "return a.filter!(c => c==b.front);" by "return a.filter!(c => true);" the problem remains (but now you can use lazy). As I'm not an expert myself, I'm not sure how to analyze this. But I think, both parameters to "choose" are evaluated (that is they are not lazy), but "myFilter" uses it's parameter immediately to give "b" a value, while "filter" just hands in an anonymous function without using it ever. Hope, this helps to get further down the way to a solution...
Re: Why does choose not work here
On Thursday, 1 August 2019 at 21:12:51 UTC, ag0aep6g wrote: `choose`'s parameters aren't lazy. So the second argument is evaluated even when `previous is null`. That means `intervalRange` is called on a null `previous`. And that fails, of course, because `intervalRange` can't access `starts` or `stops` when `this` is null. I forgot about lazy parameters. I tried changes myFilters second parameter to lazy, but that didn't help. So I guess I'm stuck with the "if" version using the ForwardRange interface (version 2)? Anyone have any other thoughts?
Re: Why does choose not work here
On 01.08.19 22:23, Matt wrote: Version 4 does not work when PairedA.previous is null. I'd love to understand why. [...] auto myFilter(R1, R2)(R1 a, R2 b) { import std.algorithm : filter, canFind; return a.filter!(c => b.canFind(c)); } struct A { uint[] starts, stops; import std.range : ForwardRange, inputRangeObject; import std.typecons : Tuple; ForwardRange!(Tuple!(uint,uint)) intervalRange() @property { import std.algorithm : map; import std.range : zip; import std.typecons : tuple; return zip(starts,stops).map!(a => tuple(a[0],a[1])).inputRangeObject; } } struct PairedA { [...] //version 4 auto uniqIntervals() @property { import std.range : choose; import std.algorithm : filter, canFind; return choose(previous is null, primary.intervalRange, primary.intervalRange .myFilter(previous.intervalRange)); } A primary; A* previous; } `choose`'s parameters aren't lazy. So the second argument is evaluated even when `previous is null`. That means `intervalRange` is called on a null `previous`. And that fails, of course, because `intervalRange` can't access `starts` or `stops` when `this` is null.
Why does choose not work here
I'm having some trouble with a "Program exited with code -1073741819" error in some code I'm writing and I would appreciate any help/insight. The problem stems from some incompatibility between the Phobos function "choose" and the template function "myFilter" which returns a range. The code below is a simplified version of what I'm trying to do. myFilter is a dummy/stand-in function that highlights the error in my program (i.e. My function is not simply a filter; it is much more complicated but unnecessary to highlight my problem). In PairedA, sometimes previous will be null. I need the uniqIntervals member function to do the right thing depending on if previous is null or not. In an ideal situation uniqIntervals would return a forward range where the work would be done in a lazy fashion. Version 1 works but is not lazy and does not use choose. Version 2 works but requires converting the ranges to ForwardRange classes, (I'd prefer to not use an unnecessary level of indirection). Version 3 uses the Phobos function filter which works inside choose (but there is no Phobos function that can actual do why myFilter stands in for. It's just interesting that the Phobos function works where myFilter doesn't as they are both template functions. Version 4 does not work when PairedA.previous is null. I'd love to understand why. I'd also love to some one to show me what the best way to do this would be. If version 2 is the best I can do, I'll live with it. Thanks so much, the code is below: auto myFilter(R1, R2)(R1 a, R2 b) { import std.algorithm : filter, canFind; return a.filter!(c => b.canFind(c)); } struct A { uint[] starts, stops; import std.range : ForwardRange, inputRangeObject; import std.typecons : Tuple; ForwardRange!(Tuple!(uint,uint)) intervalRange() @property { import std.algorithm : map; import std.range : zip; import std.typecons : tuple; return zip(starts,stops).map!(a => tuple(a[0],a[1])).inputRangeObject; } } struct PairedA { //version 1 // auto uniqIntervals() @property // { // import std.array : array; // if (previous is null) return primary.intervalRange.array; // return primary.intervalRange // .myFilter(previous.intervalRange).array; // } //version 2 // import std.range : ForwardRange, inputRangeObject; // import std.typecons : Tuple; // ForwardRange!(Tuple!(uint,uint)) uniqIntervals() @property // { // if (previous is null) return primary.intervalRange.inputRangeObject; // return primary.intervalRange // .myFilter(previous.intervalRange).inputRangeObject; // } //version 3 // auto uniqIntervals() @property // { // import std.range : choose; // import std.algorithm : filter, canFind; // return choose(previous is null, // primary.intervalRange, // primary.intervalRange // .filter!(a => previous.intervalRange.canFind(a))); // } //version 4 auto uniqIntervals() @property { import std.range : choose; import std.algorithm : filter, canFind; return choose(previous is null, primary.intervalRange, primary.intervalRange .myFilter(previous.intervalRange)); } A primary; A* previous; } unittest { uint[] startsA = [1,100,1000,1]; uint[] stopsA = [2,200,2000,2]; uint[] startsB = [1,100]; uint[] stopsB = [2,200]; auto a1 = A(startsA, stopsA); auto a2 = A(startsB, stopsB); auto p = PairedA(a1, ); auto p2 = PairedA(a1, null); import std.stdio : writeln; writeln(p.uniqIntervals);//always works writeln(p2.uniqIntervals);//Program exited with code -1073741819 for version 4 }
Re: Why does not UFCS work for method defined inside unittest block?
On Tuesday, 31 July 2018 at 08:42:28 UTC, Simen Kjærås wrote: From https://dlang.org/spec/function.html#pseudo-member: "A free function can be called with a syntax that looks as if the function were a member function of its first parameter type." [...] Thanks a lot Simen :)
Re: Why does not UFCS work for method defined inside unittest block?
On Tuesday, 31 July 2018 at 08:28:01 UTC, Ky-Anh Huynh wrote: Hi, Can I define a new quick function to use inside a unittest block? I have the following code: [code] auto foo(string[] sta) { return sta; } auto bar(string[] sta) { return sta; } auto h(string[] sta) { return sta.foo.bar; } unittest { import std.format; auto f = (string[] sta) => sta.foo.bar; auto g(string[] sta) { return sta.foo.bar; } assert(f(["test"]) == ["test"]); assert(g(["test"]) == ["test"]); assert(["test"].h == ["test"]); assert(["test"].g == ["test"]); } [/code] (Src: https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a) The last test will fail: Error: no property g for type string[] Please advise. From https://dlang.org/spec/function.html#pseudo-member: "A free function can be called with a syntax that looks as if the function were a member function of its first parameter type." A function defined in a function scope (which a unittest block is), is not a free function, and so does not benefit from UFCS. There is an explanation for why at the bottom of the above page: "The reason why local symbols are not considered by UFCS, is to avoid unexpected name conflicts." If you need a function that's available for UFCS in a unittest but is not there in a non-unittest context, use a version block: version (unittest) { auto fun(string[] s) { return s } } And if you need something with a context: version (unittest) { string delegate (string) test; } unittest { string s1 = "foo"; test = s => s ~ s1; "foo".test; } -- Simen
Re: Why does not UFCS work for method defined inside unittest block?
dmd version that I'm using: $ dmd --version DMD64 D Compiler v2.081.1-dirty Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved written by Walter Bright
Why does not UFCS work for method defined inside unittest block?
Hi, Can I define a new quick function to use inside a unittest block? I have the following code: [code] auto foo(string[] sta) { return sta; } auto bar(string[] sta) { return sta; } auto h(string[] sta) { return sta.foo.bar; } unittest { import std.format; auto f = (string[] sta) => sta.foo.bar; auto g(string[] sta) { return sta.foo.bar; } assert(f(["test"]) == ["test"]); assert(g(["test"]) == ["test"]); assert(["test"].h == ["test"]); assert(["test"].g == ["test"]); } [/code] (Src: https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a) The last test will fail: Error: no property g for type string[] Please advise. Thanks a lot.
Re: Why does this not work?
On Friday, 1 January 2016 at 14:00:41 UTC, TheDGuy wrote: writeln("Which number should i guess?"); string input = readln(); int i = to!int(input); You fell for the C# syntax like me... According to Ahli. You have to use the old C way of doing it with readf.
Re: Why does this not work?
On Friday, 1 January 2016 at 14:00:41 UTC, TheDGuy wrote: writeln("Which number should i guess?"); string input = readln(); int i = to!int(input); The solution is that readln() returns a string that also contains the newline this can be solved by easily stripping the newline off import std.string; int i = to!int(input.strip);
Re: Why does this not work?
On Friday, 1 January 2016 at 14:20:26 UTC, Tobi G. wrote: The solution is that readln() returns a string that also contains the newline this can be solved by easily stripping the newline off import std.string; int i = to!int(input.strip); Sorry my bad english.. i wrote solution but meant problem
Re: Why does this not work?
On Friday, 1 January 2016 at 14:47:20 UTC, TheDGuy wrote: On Friday, 1 January 2016 at 14:29:34 UTC, Tobi G. wrote: On Friday, 1 January 2016 at 14:20:26 UTC, Tobi G. wrote: The solution is that readln() returns a string that also contains the newline this can be solved by easily stripping the newline off import std.string; int i = to!int(input.strip); Sorry my bad english.. i wrote solution but meant problem Thank you very much! That helped me alot. It is kind of hard if you don't have the background knowledge... I've battled with a few times, not having any idea what was going on. I now almost automatically use strip when it's not working.
Why does this not work?
writeln("Which number should i guess?"); string input = readln(); int i = to!int(input);
Re: Why does this not work?
On Friday, 1 January 2016 at 14:29:34 UTC, Tobi G. wrote: On Friday, 1 January 2016 at 14:20:26 UTC, Tobi G. wrote: The solution is that readln() returns a string that also contains the newline this can be solved by easily stripping the newline off import std.string; int i = to!int(input.strip); Sorry my bad english.. i wrote solution but meant problem Thank you very much! That helped me alot. It is kind of hard if you don't have the background knowledge...
Re: Why does this not work?
On Friday, 1 January 2016 at 15:06:53 UTC, bachmeier wrote: I've battled with a few times, not having any idea what was going on. I now almost automatically use strip when it's not working. This is one of the most frequently asked questions by new users.. I added a tip to my new docs: http://dpldocs.info/experimental-docs/std.stdio.readln.html If you were looking at that for the first time, would you notice it? If no, I can see about moving it or rewording it or something.
Re: Why does this not work?
On Friday, 1 January 2016 at 15:16:36 UTC, Adam D. Ruppe wrote: On Friday, 1 January 2016 at 15:06:53 UTC, bachmeier wrote: I've battled with a few times, not having any idea what was going on. I now almost automatically use strip when it's not working. This is one of the most frequently asked questions by new users.. I added a tip to my new docs: http://dpldocs.info/experimental-docs/std.stdio.readln.html If you were looking at that for the first time, would you notice it? If no, I can see about moving it or rewording it or something. If i had known that blog existed. I think your example at the end of the page explains the problem really well. Thanks!
Re: Why does this not work?
On Friday, 1 January 2016 at 17:00:23 UTC, TheDGuy wrote: If i had known that blog existed. I think your example at the end of the page explains the problem really well. Thanks! I just wrote that example in response to this thread :P (the overall thing there is something i started last week to reorganize the official docs to be easier to read and edit) But it is a common enough question that it should just be in the documentation.
Re: Why does this not work?
On Friday, 1 January 2016 at 15:16:36 UTC, Adam D. Ruppe wrote: On Friday, 1 January 2016 at 15:06:53 UTC, bachmeier wrote: I've battled with a few times, not having any idea what was going on. I now almost automatically use strip when it's not working. This is one of the most frequently asked questions by new users.. I added a tip to my new docs: http://dpldocs.info/experimental-docs/std.stdio.readln.html If you were looking at that for the first time, would you notice it? If no, I can see about moving it or rewording it or something. If the user is reading the docs completely, yes, it is clear. It would probably be better to put it in its own section, because a user might not expect to find an explanation of a pitfall in there, and because it makes it easy to find when you're looking the second or third time.
Re: Why does sum not work in static arrays?
On Sunday, 6 December 2015 at 12:23:05 UTC, Tim K. wrote: Hi! I have the following code: int main(string[] argv) { import std.algorithm: sum; import std.stdio: writeln; uint[3] a1 = [1, 2, 3]; uint[] a2; for (int i = 1; i <= 3; ++i) a2 ~= i; writeln("a1: ", sum(a1)); writeln("a2: ", sum(a2)); return 0; } This throws the error: dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(3916): std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))) /usr/include/dmd/phobos/std/algorithm/iteration.d(3927): std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front))) So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays? Regards So that you do not shoot yourself in the foot too easily. A static array is a value type so it is passed by value to functions. If you pass a 1M array to a function... well, I guesse you don't want to do that. The solution is to slice it: a1[].sum; That way you avoid the problem.
Re: Why does sum not work in static arrays?
06.12.2015 15:23, Tim K. пишет: Hi! I have the following code: int main(string[] argv) { import std.algorithm: sum; import std.stdio: writeln; uint[3] a1 = [1, 2, 3]; uint[] a2; for (int i = 1; i <= 3; ++i) a2 ~= i; writeln("a1: ", sum(a1)); writeln("a2: ", sum(a2)); return 0; } This throws the error: dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(3916): std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))) /usr/include/dmd/phobos/std/algorithm/iteration.d(3927): std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front))) So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays? Regards Because static array aren't ranges, but dynamic ones are. Try this: writeln("a1" ", sum (a1[])); // using [] makes static array to be a range
Why does sum not work in static arrays?
Hi! I have the following code: int main(string[] argv) { import std.algorithm: sum; import std.stdio: writeln; uint[3] a1 = [1, 2, 3]; uint[] a2; for (int i = 1; i <= 3; ++i) a2 ~= i; writeln("a1: ", sum(a1)); writeln("a2: ", sum(a2)); return 0; } This throws the error: dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are: /usr/include/dmd/phobos/std/algorithm/iteration.d(3916): std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front))) /usr/include/dmd/phobos/std/algorithm/iteration.d(3927): std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front))) So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays? Regards
Re: Why does sum not work in static arrays?
On Sunday, 6 December 2015 at 12:27:49 UTC, cym13 wrote: A static array is a value type so it is passed by value to functions. Oh, right, I totally forgot about that. Thank you for reminding me. And yes, I was not planning on doing that. I just have a local fixed-size array that I wanted to get the sum of... The solution is to slice it: a1[].sum; That way you avoid the problem. Thank you two. Regards
Why does this not work?
void func( int c ) { ubyte a; a = cast(ubyte)c + cast(ubyte)c; } dmd v2.065 complains about: test.d(5): Error: cannot implicitly convert expression (cast(int)cast(ubyte)c + cast(int)cast(ubyte)c) of type int to ubyte As far as I can tell, adding two values of the same type should result in the same type. Shachar
Re: Why does this not work?
the result of ubyte + ubyte is int I believe. Try; void func( int c ) { ubyte a; a = cast(ubyte)(cast(ubyte)c + cast(ubyte)c); }
Re: Why does this not work?
On Wed, 17 Sep 2014 13:20:13 + Shachar via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: From http://dlang.org/type, under Usual Arithmetic Conversions: 4. Else the integer promotions are done on each operand, followed by: 1. If both are the same type, no more conversions are done. it's bug in specs, i believe, 'cause compiler promotes smaller types to int/uint. signature.asc Description: PGP signature
Re: Why does this not work?
On 17/09/14 16:32, ketmar via Digitalmars-d-learn wrote: On Wed, 17 Sep 2014 13:20:13 + Shachar via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: From http://dlang.org/type, under Usual Arithmetic Conversions: 4. Else the integer promotions are done on each operand, followed by: 1. If both are the same type, no more conversions are done. it's bug in specs, i believe, 'cause compiler promotes smaller types to int/uint. I don't understand. Why is this behavior preferrable to the one outlined by the specs? Thanks, Shachar
Re: Why does this not work?
Because of overflow. On Wednesday, 17 September 2014 at 13:36:42 UTC, Shachar Shemesh wrote: On 17/09/14 16:32, ketmar via Digitalmars-d-learn wrote: On Wed, 17 Sep 2014 13:20:13 + Shachar via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: From http://dlang.org/type, under Usual Arithmetic Conversions: 4. Else the integer promotions are done on each operand, followed by: 1. If both are the same type, no more conversions are done. it's bug in specs, i believe, 'cause compiler promotes smaller types to int/uint. I don't understand. Why is this behavior preferrable to the one outlined by the specs? Thanks, Shachar
Re: Why does this not work?
On Wed, 17 Sep 2014 16:36:41 +0300 Shachar Shemesh via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: I don't understand. Why is this behavior preferrable to the one outlined by the specs? 'cause C does exactly this. there is no reason to confuse people with C background by silently removing such feature. signature.asc Description: PGP signature
Re: Why does this not work?
http://www.drdobbs.com/tools/value-range-propagation/229300211
Re: Why does this not work?
On Wednesday, 17 September 2014 at 13:20:15 UTC, Shachar wrote: On Wednesday, 17 September 2014 at 13:03:05 UTC, flamencofantasy wrote: the result of ubyte + ubyte is int I believe. Try; void func( int c ) { ubyte a; a = cast(ubyte)(cast(ubyte)c + cast(ubyte)c); } From http://dlang.org/type, under Usual Arithmetic Conversions: 4. Else the integer promotions are done on each operand, followed by: 1. If both are the same type, no more conversions are done. So, as far as I can see, the specs disagree with you. You missed that integer promotions are done first. http://dlang.org/type.html#Integer%20Promotions: Integer Promotions are conversions of the following types: [...] fromto [...] ubyte int [...] So, integer promotions turn ubyte + ubyte into int + int.
Why does toUTF16z only work with UTF8 encoding?
toUTF16 can take a char[], wchar[] or dchar[]. But toUTF16z can only take a char[]. Why? I'm storing some text as dchar[] internally and have to pass it to WinAPI Unicode functions which expect null-terminated UTF16 strings. But toUTF16z only works with char[] for some reason.
Re: Why does toUTF16z only work with UTF8 encoding?
I guess this should do it: const(wchar)* toUTF16z(in dchar[] s) { return (toUTF16(s) ~ \000).ptr; }