Re: Trouble using 'sort'
On 07/26/2016 11:42 AM, drug wrote: > Another option is `makeIndex` (std.algorithm.sorting) and then sorting > of that index. That's an interesting option; at least I don't have to touch the range. Thanks. -- Bahman
Re: Trouble using 'sort'
On 07/26/2016 10:41 AM, Jonathan M Davis via Digitalmars-d-learn wrote: >> So it may be something about what kind of range I'm passing to `sort`. >> Am I right? > > sort requires a random access range. Without knowing exactly which > algorithms your using, I can't say for sure that that's the problem, but > usually it is. Most of the time, you don't end up with a random access range > after chaining several range-based functions. You _can_, but it depends > entirely on which functions they are and the type of your original range. > > It's frequently the case that if you want to sort a range, you have to call > array() on it to convert it to an array, and then you can sort the array. Thanks...that explains it. -- Bahman
Re: Trouble using 'sort'
On 07/26/2016 10:11 AM, Bahman Movaqar wrote: > Alright...further experiments. The following works: > > sort!((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(theRange) > > So it may be something about what kind of range I'm passing to `sort`. > Am I right? > I meant sort!((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(theRange.array) -- Bahman
Re: Trouble using 'sort'
On 07/26/2016 09:35 AM, Bahman Movaqar wrote: > I have a range which is the result of a couple of chained range > operations, and each element is: > > Tuple!(string, "product", double, "price") > > Now I'd like to sort the range by "price" using: > > sort!((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(theRange) > > But I get a compile time error: > > source/services.d(166,63): Error: template std.algorithm.sorting.sort > cannot deduce function from argument types !((pp1, pp2) => > cmp(pp1.price, pp2.price) > 0)(MapResult!(__lambda5, Result)), > candidates are: > /home/bahman/Programs/D/dmd-2.071.0/linux/bin64/../../src/phobos/std/algorithm/sorting.d(1027,1): >std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss > = SwapStrategy.unstable, Range)(Range r) if ((ss == > SwapStrategy.unstable && (hasSwappableElements!Range || > hasAssignableElements!Range) || ss != SwapStrategy.unstable && > hasAssignableElements!Range) && isRandomAccessRange!Range && > hasSlicing!Range && hasLength!Range) > source/services.d(168,5): Error: var has no effect in expression (theRange) > dmd failed with exit code 1. Alright...further experiments. The following works: sort!((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(theRange) So it may be something about what kind of range I'm passing to `sort`. Am I right? -- Bahman
Trouble using 'sort'
I have a range which is the result of a couple of chained range operations, and each element is: Tuple!(string, "product", double, "price") Now I'd like to sort the range by "price" using: sort!((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(theRange) But I get a compile time error: source/services.d(166,63): Error: template std.algorithm.sorting.sort cannot deduce function from argument types !((pp1, pp2) => cmp(pp1.price, pp2.price) > 0)(MapResult!(__lambda5, Result)), candidates are: /home/bahman/Programs/D/dmd-2.071.0/linux/bin64/../../src/phobos/std/algorithm/sorting.d(1027,1): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range) source/services.d(168,5): Error: var has no effect in expression (theRange) dmd failed with exit code 1. And I have no clue what it is complaining about. I'd really appreciate any hint/help on this. Thanks, -- Bahman
Re: Trouble checking for null-ness
On 07/25/2016 05:47 PM, Adam D. Ruppe wrote: > On Monday, 25 July 2016 at 13:09:22 UTC, Bahman Movaqar wrote: >> From what I could gather, it's not possible to check for `null` at >> runtime for reference based types. Am I right? > > No, it is only possible to check for null for reference based types. But > map's result is not a reference based type. Oh, I see now. Thanks. -- Bahman
Re: Trouble checking for null-ness
On 07/25/2016 05:07 PM, Bahman Movaqar wrote: > Suppose I have the following function: > > public auto max(alias comp, Range)(Range r) > in { > assert(r !is null && !r.empty); > } > body { > // ... > } > > When the function after a series of chained `map` operations, I get the > following error: > > Error: incompatible types for ((r) !is (null)): > 'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)' > > Of course if I remove `r !is null` from the `in` block, everything will > work. But I'm curious; how can I check for a `null` in this case? Thank you people for the answers. >From what I could gather, it's not possible to check for `null` at runtime for reference based types. Am I right? -- Bahman
Trouble checking for null-ness
Suppose I have the following function: public auto max(alias comp, Range)(Range r) in { assert(r !is null && !r.empty); } body { // ... } When the function after a series of chained `map` operations, I get the following error: Error: incompatible types for ((r) !is (null)): 'MapResult!(__lambda2, SInvoiceLine[])' and 'typeof(null)' Of course if I remove `r !is null` from the `in` block, everything will work. But I'm curious; how can I check for a `null` in this case? Thanks, -- Bahman
Re: unittests not being run
On 07/17/2016 12:38 AM, Seb wrote: > There is no need for a module, but dub by default only checks files in > the 'source' folder. The file is already in the 'source' folder. > For such simple tests you could also run them directly with rdmd > -unittest. There is an additional -main flag if you don't need a main > method. Indeed, that's a slimmed down version of my code. Though the real code is different (not this simple and already has a `main`) the problem is the same. -- Bahman
Re: unittests not being run
On 07/15/2016 04:16 PM, Jerry wrote: > Unittests have to be inside a module to be run on DMD atleast. > So putting module foo at top should fix it. Strange. Still not getting picked up. $ dmd --version DMD64 D Compiler v2.071.0 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright [app.d] module app; import std.stdio; private int incBy1(int i) { return i + 1; } unittest { assert(incBy1(1) == 200); } void main() { writeln(incBy1(1)); // which prints 2 } [/app.d] $ dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86_64. dplay ~master: building configuration "__test__library__"... Linking... Running ./__test__library__ All unit tests have been run successfully. -- Bahman
unittests not being run
The test I have in 'app.d' don't get picked up by 'dub test' in a freshly created project by 'dub init'. $ dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86_64. dplay ~master: building configuration "__test__library__"... Linking... Running ./__test__library__ All unit tests have been run successfully. [app.d] import std.stdio; private int incBy1(int i) { return i + 1; } unittest { assert(foo(1) == 200); } void main() { writeln("hi"); } What am I missing? Thanks in advance, -- Bahman
Experimenting with templates
Following up my D practices, I've created a 'groupBy' template[1] for Stockman (my practice project). I'd like to ask you more experienced folks to please take a look at it. As this is my first template, I'd like to know if I am doing anything idiomatically/logically wrong. PS: I've also implemented two simple function templates (all[1] and contains[2]) because the versions from dlib didn't appeal to my sense of usage beauty :-) [1] https://github.com/bahmanm/stockman-d/blob/master/source/rangeutils.d#L38 [2] https://github.com/bahmanm/stockman-d/blob/master/source/rangeutils.d#L105 [3] https://github.com/bahmanm/stockman-d/blob/master/source/rangeutils.d#L129 -- Bahman
Re: Docs for `Group` type
On 07/12/2016 04:21 PM, Edwin van Leeuwen wrote: > On Tuesday, 12 July 2016 at 11:40:48 UTC, Bahman Movaqar wrote: >> On 07/12/2016 01:01 PM, Mike Parker wrote: >>> Do you have some sample code that shows the error? >> >> Yes. I'm working on Stockman[1] a playground to learn D. >> In file `etl.d`, line 110 [2], if I change the line to >> auto refInvoice = group[1].takeOne(); >> the file will not compile. I have attached the compile error to this >> message. >> >> Thanks, > > What does group.writeln; output? That should give you a good sense of > what is going on. That's a good trick to know. Thanks. -- Bahman
Re: Docs for `Group` type
On 07/12/2016 04:23 PM, ag0aep6g wrote: > On 07/12/2016 01:40 PM, Bahman Movaqar wrote: >> Yes. I'm working on Stockman[1] a playground to learn D. >> In file `etl.d`, line 110 [2], if I change the line to >> auto refInvoice = group[1].takeOne(); >> the file will not compile. I have attached the compile error to this >> message. > > Do you also add the import of takeOne? takeOne is not a range primitive, > but a function that works on ranges. Need to import it in order to use it. Stupid me! Thanks :-) -- Bahman
Re: Docs for `Group` type
On 07/12/2016 01:01 PM, Mike Parker wrote: > Do you have some sample code that shows the error? Yes. I'm working on Stockman[1] a playground to learn D. In file `etl.d`, line 110 [2], if I change the line to auto refInvoice = group[1].takeOne(); the file will not compile. I have attached the compile error to this message. Thanks, -- Bahman [1] https://github.com/bahmanm/stockman-d [2] https://github.com/bahmanm/stockman-d/blob/master/source/etl.d#L110 Performing "debug" build using dmd for x86_64. stockman-d ~master: building configuration "application"... source/etl.d(110,33): Error: no property 'takeOne' for type 'ChunkByChunkImpl!(__lambda9, MapResult!(__lambda3, ByLine!(char, char)))' /home/bahman/Programs/D/dmd-2.071.0/linux/bin64/../../src/phobos/std/algorithm/iteration.d(480,16):instantiated from here: MapResult!(__funcliteral3, ChunkByImpl!(__lambda2, MapResult!(__lambda3, ByLine!(char, char source/etl.d(108,44):instantiated from here: map!(ChunkByImpl!(__lambda2, MapResult!(__lambda3, ByLine!(char, char source/etl.d(32,26):instantiated from here: combineOneLiners!(MapResult!(__lambda3, ByLine!(char, char))) dmd failed with exit code 1.
Re: Docs for `Group` type
On 07/12/2016 11:06 AM, Mike Parker wrote: > The 'Group' type is an implementation detail -- a type used internally > -- that you aren't supposed to care about. All you need to care about is > that it's a range. The documentation for chunkBy [1] explains what the > return type is. > > [1] https://dlang.org/phobos/std_algorithm_iteration.html#.chunkBy Thanks. Now since I can't do `takeOne` on `Group`[1], exactly what kind of range is `Group`? [1] Error: no property 'takeOne' for type 'Group' -- Bahman
Re: Passing ranges around
On 07/12/2016 11:07 AM, Mike Parker wrote: > auto foo(R)(R r) { ... } That did it. Thanks. Out of curiosity, does the same pattern apply to functions which take `tuple`s as input arguments? -- Bahman
Docs for `Group` type
When using `chunkBy` (unary pred) the result is a list of tuples. Each tuple holds a key and a `Group` which belong to that key. Where can I find the docs for this `Group` type (I have already tried searching library on dlang.org)? Thanks, -- Bahman
Re: Associative Array c'tor
On 07/11/2016 07:15 PM, Ali Çehreli wrote: > Both AAs and slices behave like reference types even when passed by > value: When a function adds an element, the argument sees that element > as well. This is not the case when the argument is an empty (more > correctly, null) AA or slice: > > void foo(string[int] aa) { > aa[1] = "one"; > } > > void main() { > string[int] a; > foo(a); > assert(a is null); > // The last result would be different if 'a' were not null > // before calling 'foo'. > > string[int] b; > b[0] = "zero"; > foo(b); > assert(b[0] == "zero"); > assert(b[1] == "one"); > } Now I understand. This is tricky --could introduce hard to find bugs. Is there anyway to make sure it doesn't happen? Such as giving the AA a default empty value on the declaration line --like `string[int] a = []`? > P.P.S. There is std.algorithm.fold, which works with range chaining > (unlike reduce, which was designed before ranges): > > https://dlang.org/phobos/std_algorithm_iteration.html#.fold `fold` definitely feels more natural. Thanks. -- Bahman
Re: How to use `format` to repeat a character
On 07/11/2016 03:02 PM, Mike Parker wrote: > You can do it in D with custom format specifiers. See: > > https://wiki.dlang.org/Defining_custom_print_format_specifiers Thanks for the pointer. I'll keep that in mind. -- Bahman
Re: Associative Array c'tor
On 07/11/2016 06:30 PM, Steven Schveighoffer wrote: > Untested, but you could try MySt[][string].init. That did it. Thanks. > But passing empty AA by value sometimes can be surprising. I'm not sure > if it will work. Could you elaborate more? -- Bahman
Associative Array c'tor
I'm processing a list of structs (MySt) with `reduce` to produce an associate array of type `MySt[][string]`. Right now I'm using the following (slimmed down) code: MySt[][string] result; return reduce!( function MySt[][string](MySt[][string] acc, MySt val) { // do something with acc return acc; } )(result, inputList); I was wondering if I could remove the empty declaration line (line 1); for example: return reduce!( function MySt[][string](MySt[][string] acc, MySt val) { // do something with acc return acc; } )(new MySt[][string](), inputList); Obviously, this fails with the error message: "cannot pass type string as a function argument". I very much would like to avoid empty declaration lines like that of `result`. Is there anyway you folks would suggest? Thanks in advance, -- Bahman
Re: How to use `format` to repeat a character
On 07/11/2016 02:44 PM, ketmar wrote: > On Monday, 11 July 2016 at 09:31:49 UTC, Ali Çehreli wrote: >> What makes you expect that format should have that feature? :) I somehow recalled I could do that in C and then there was the "minimum field width" in the docs, so I thought it's possible I'm just not understanding the docs clearly :-) > the fact that format can insert spaces. it is like: "ok, it can do > spaces. i bet there should be some way to use any character instead of > space. after all, the implementation would be the same, right?!" and > then... oops. That's my story. Thanks people for your help.
How to use `format` to repeat a character
I'm sure I'm missing something very simple but how can I create a string like "" using `format`? I check the docs on `format` and tried many variations including `format("%.*c\n", 4, '-')` but got nowhere. I'd appreciate any hint/help on this. -- Bahman Movaqar http://BahmanM.com - https://twitter.com/bahman__m https://github.com/bahmanm - https://gist.github.com/bahmanm PGP Key ID: 0x6AB5BD68 (keyserver2.pgp.com)
Difference between back (`) and double (") quoted strings
Is there any or they are just simply syntactically equivalent? Are there any official docs on this? -- Bahman Movaqar http://BahmanM.com - https://twitter.com/bahman__m https://github.com/bahmanm - https://gist.github.com/bahmanm PGP Key ID: 0x6AB5BD68 (keyserver2.pgp.com) signature.asc Description: OpenPGP digital signature
Re: How To: Passing curried functions around
On Friday, 11 September 2015 at 21:06:32 UTC, Ali Çehreli wrote: On 09/11/2015 02:04 PM, Ali Çehreli wrote: The same keyword has a different use with templates: And the official documentation: http://dlang.org/template.html#TemplateAliasParameter Thanks again!
Re: Difference between back (`) and double (") quoted strings
On 09/12/2015 12:52 PM, NX wrote: > What if I told you, you should search the official reference before > asking such things in the forum? I did search the net for terms such as "d lang back quoted string" or "d lang multi line string" or "d lang string interpolation" before asking here. However the term "Wysiwyg string" didn't occur to my mind and from what I could gather from the net and the test programs I wrote, I couldn't determine the difference between `-string and "=string. Hence I decided to ask people here. > http://dlang.org/lex.html#WysiwygString Thanks for the help. -- Bahman Movaqar http://BahmanM.com - https://twitter.com/bahman__m https://github.com/bahmanm - https://gist.github.com/bahmanm PGP Key ID: 0x6AB5BD68 (keyserver2.pgp.com)
Re: Adjacent Pairs Range
On 09/12/2015 02:47 PM, "Nordlöw" wrote: > How do I most elegantly iterate all the adjacent pairs in an > `InputRange` using Phobos? > > Something like > > [1,2,3,4] => [(1,2), (2,3), (3,4)] That's call `collate`ing IIRC. A quick solution would be using `std.range.transposed`: auto a = [1,2,3,4]; auto ll = [a, a[1..$]]; transpose(ll); // returns [[1, 2], [2, 3], [3, 4], [4]] Though you have to take care of the dangling last element yourself. -- Bahman Movaqar
Re: Adjacent Pairs Range
On 09/12/2015 04:04 PM, Bahman Movaqar wrote: > Oops! Here's one using only `InputRange` interface: I believe I need to warn you that I'm just learning D; so take my solution at your own risk :-) -- Bahman Movaqar
Re: Adjacent Pairs Range
On 09/12/2015 03:09 PM, "Nordlöw" wrote: > InputRange please, not RandomAccessRanges ;) Oops! Here's one using only `InputRange` interface: T[][] collate(T)(T[] a) { alias CollateResult = Tuple!(T[][], "result", T, "tlHd"); CollateResult _collate(CollateResult collres) { if (!a.empty) { auto newTlHd = a.front; a.popFront(); return _collate( CollateResult( collres.result ~ [collres.tlHd, newTlHd], newTlHd ) ); } else { return collres; } } if (!a.empty) { auto tlHd = a.front; a.popFront(); return _collate( CollateResult([], tlHd) ).result; } else { return []; } } unittest { writeln([10, 20, 30].collate!int); } -- Bahman Movaqar
Multiple implicit type converters
As only one `alias this` is possible for any type, how should one implement multiple implicit type converters? Actually I'm looking for something similar to Groovy's `asType` method[1]. An example in Groovy: Point p = new Point(1, 1) assert (p as BigDecimal[]) == [1, 1] assert (p as BigDecimal) == Math.sqrt(2) assert (p as Region) == new Region(p, p) This allows for multiple type converters which are *explicit* --in contrast to `alias this` implicit nature. [1] http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Collection.html#asType%28java.lang.Class%29
Re: What is "FilterResult" type?
On Wednesday, 9 September 2015 at 13:16:49 UTC, cym13 wrote: True. But is pumping the output of `filter` as the seed into `reduce` really considered weird usage!? I don't think it is really weird per se, I just can't think of a case where there isn't a better way to do it. I find it completely unreadable frankly, and I generally avoid reduce when I can because it is not UFCS-able. This is only personal opinion though. Now I see your point. I too find fold/reduce the least transparent verb of the list comprehension. And certainly your point about UFCS adds to it.
Re: How To: Passing curried functions around
On Friday, 11 September 2015 at 06:14:18 UTC, Ali Çehreli wrote: On 09/06/2015 12:05 PM, Bahman Movaqar wrote: > alias bool function(int n) validator_t; There is the relatively newer alias syntax which is more intuitive: alias Validator = bool function(int n); Great. This is easily read by my eyes. partial takes the function arguments as 'value template parameters'. Unfortunately, a function pointer like cannot be 'value template parameters'; only fundamental types and strings can... So, 'partial' is not an option for this problem. Ah...now I understand the mysterious compiler errors. Idiomatic D uses templates and passes behavior in the form of 'alias template parameters.' Alias template parameters are the convenient way of allowing anything that is callable, not just functions. For example, foo() would be much more useful if it allowed a delegate or a class object that has an overloaded opCall() operator. True. I guess I was just pushing D functions too far. > and even > if this is the correct way of currying `readInt`, what should be the > signature of `foo`? I think 'int delegate()' would do because all foo needs is a function that returns an int. That's correct. I realised this subtle point later on, but had already switched to a `struct`y approach. The idiomatic way is to leave it as a template parameter. However, this has the problem of making each instantiation of the foo template a different type, making them incompatible to be elements of the same array: [ &(foo!myReader), &(foo!yourReader) ] // <-- compilation error One solution is to do what std.parallelism.task does: to provide both a foo template and another foo function that takes an 'int delegate()': http://ddili.org/ders/d.en/parallelism.html (Search for "The task function above has been specified as a template parameter" on that page.) Actually, I *am* using your book (which is, by the way, very well written) plus the language specs to learn D. However, that section yet too advance for me to touch :-) import std.stdio; bool isEven(int n) { return !(n % 2); } int readValidInt(alias validator)(string prompt) { while (true) { int i; write(prompt); readf(" %s", ); if (validator(i)) { return i; } else { writeln("Sorry, that's not acceptable"); } } } void foo(alias reader)() { reader(); } void main() { auto reader = () => readValidInt!isEven("Enter an integer: "); foo!reader(); } You can add template constraints to make the code easier to use. Clean one! Even though I don't know what's going behind the scenes, I can easily read and understand it. Thanks for the help.
Re: Multiple implicit type converters
On Friday, 11 September 2015 at 19:51:09 UTC, Dave Akers wrote: That's enough for me, I suppose. I am thinking of having a family of functions in my structs/classes as `as` family, such as `asDouble`, `asFooBar`. Would it be possible to create it as an 'as' template? Hmm...there's already the `to` template, right?
Re: Multiple implicit type converters
On Friday, 11 September 2015 at 16:33:52 UTC, Meta wrote: The only ways to get implicit conversion between two types in D are through `alias this`, inheritance, or implementing an interface. That's enough for me, I suppose. I am thinking of having a family of functions in my structs/classes as `as` family, such as `asDouble`, `asFooBar`.
Re: Multiple implicit type converters
On Friday, 11 September 2015 at 16:31:46 UTC, Adam D. Ruppe wrote: explicit is the only way to go. That's easy to do, just write like a .get method or something that does the conversion and returns it. Fair enough. Type conversion is one of those spots that I'd like it to as explicit as possible.
Re: How To: Passing curried functions around
On Friday, 11 September 2015 at 18:39:15 UTC, Ali Çehreli wrote: >> import std.stdio; >> >> bool isEven(int n) { >> return !(n % 2); >> } >> >> int readValidInt(alias validator)(string prompt) { readValidInt() is a function template that takes two information: 1) The validator as its alias template parameter. alias template parameter allows it to work with anything that can be called. I read "alias and with" chapter of the book to understand this but couldn't find any such use for `alias` there. Does using `alias` instead of a type makes the parameter a `callable`?
Re: What is "FilterResult" type?
On Wednesday, 9 September 2015 at 07:59:57 UTC, Sebastiaan Koppe wrote: What is going wrong is that the types aren't the same. That is, the type of the seed you supplied - `typeof(foobars)` - isn't the type that your function returns - `typeof(acc.filter!...)`. Alright. So, `reduce` initial seed is an `array` while the output of `filter` is a `FilterResult`. I suppose it makes sense to realise it (`.array`) before passing to the next round. I was under the impression that `reduce` understands `FilterResult` and realises it internally; it doesn't and I was wrong. Though I believe it would have been more intuitive if it did. Thanks for the help. `array()` fixes that, no idea why you need `idup()` though. True --`idup` was not required. My mistake.
Re: What is "FilterResult" type?
On Tuesday, 8 September 2015 at 18:45:33 UTC, Jonathan M Davis wrote: If you're returning a range, you should be returning auto. @Jonathan, @cym13 and @Meta It's reasonable to use `auto`. However there are times when you need to pass the `auto` value to another function and the receiving function needs to know the type of its input arguments. In other news: Consider the following piece of code. *Please note that I am aware that the simple problem introduced can be solved in several ways which are more efficient.* immutable struct FooBar { int x; int y; } immutable(FooBar)[] foobars = [ FooBar(60, 100), FooBar(8, 20), FooBar(9, 15) ]; int[] nums = [20, 40, 55]; // // find FooBars which: // - x * y is greater than any `num` // - x and y are smaller than any `num` // auto result = reduce!( (acc, num) => acc.filter!( fb => (fb.x < num && fb.y < num) && (fb.x * fb.y > num) ) )(foobars, nums); // assert(result[0].x == 9 && result[0].y == 15); This fails to compile with the following message: Error: static assert "Incompatible function/seed/element: test.__unittestL40_4.__lambda1/immutable(FooBar)[]/int" /usr/include/dmd/phobos/std/algorithm/iteration.d(2518): instantiated from here: reduceImpl!(false, int[], immutable(FooBar)[]) /usr/include/dmd/phobos/std/algorithm/iteration.d(2502): instantiated from here: reducePreImpl!(int[], immutable(FooBar)[]) test.d(56):instantiated from here: reduce!(immutable(FooBar)[], int[]) The only way to make it work is `.array.idup` the output of `filter`. For example: auto result = reduce!( (acc, num) => acc.filter!( fb => (fb.x < num && fb.y < num) && (fb.x * fb.y > num) ).array.idup )(foobars, nums); Honestly, I cannot comprehend anything out of this; why I had to realise the lazy value and `idup` it for it to become usable by `reduce`? Does this mean that I am simply missing something obvious?
Re: What is "FilterResult" type?
On Wednesday, 9 September 2015 at 08:29:20 UTC, cym13 wrote: You are using reduce in a weird way here... Oh? Perhaps it was all because of the lame example I used :-) The real problem I was trying to solve, source of which I just pushed[1], was the `select` method on line 130. Is this idiomatic or still weird? The way I would have written it is: auto result = foobars.filter!(fb => nums.all!(n => (fb.x * fb.y) > n)) .filter!(fb => nums.all!(n => fb.x < n && fb.y < n)); For the lame example I gave, something similar occurred to me at first; but then I thought 4 `filter`s (assuming `all` is simply a `filter`) might be non-idiomatic as it might incur some performance penalty. Here you don't have any weird and completely unreadable reduce construct and don't have to realize the lazy check as std.algorithm.searching.all is lazy too. True. But is pumping the output of `filter` as the seed into `reduce` really considered weird usage!? [1] https://github.com/bahmanm/d-etudes/blob/master/source/e002/models.d
Re: What is "FilterResult" type?
On Wednesday, 9 September 2015 at 09:08:28 UTC, Atila Neves wrote: No, it doesn't. It needs to know what the compile-time interface is, i.e. what it can do with that type. If the type in question happens to be an InputRange, then the consumer function would be: void func(R)(R range) if(isInputRange!R) { ... } instead of using a concrete type like this: void func(MyType range) { ... } That way you can change range types and `func` doesn't care. Ah...makes sense. Thanks.
What is "FilterResult" type?
From what I can gather the output of `std.algorithm.iteration : filter` is a `FilterResult` type. I need a bit of help dealing with this type: 1. Why this type is there in the first place instead of simply using the type of input range? 2. Where is the documentation for this type? The documentation always uses `auto` for `filter` return values. 3. How can I convert this type back into a range? Thanks.
Re: What is "FilterResult" type?
On Tuesday, 8 September 2015 at 10:08:03 UTC, cym13 wrote: Filter is a template and returns a FilterResult range which is used to lazily compute the result. This behaviour is the same for map and the majority of functions in std.algorithm. Ah...now it makes sense why use a proxy to the results. It is an input range really (ie: it has front, popFront and empty). You can chain it just like any other range with other functions and normally don't have to know the exact type (which would be complicated since it is a templated thing). I agree. Some types are better left unspecified; like some 300+ characters long type signatures one would get from a generic Scala function :-D However, I have made this a strict practice of mine to specify the full signature of my public API. I suppose, if I want to be pedantic, I have to realise the lazy value first and pass the resulting array out. Is this correct? To store it in a variable if you don't know the exact type you can use auto to use type deduction. True. Example: Great. The usage is crystal clear to me now. If you want more precise documentation the best is to look to the source code (/usr/include/dlang/dmd/std/algorithm/iteration if you are on linux). Thanks for the help and pointers.
Re: How To: Passing curried functions around
On Monday, 7 September 2015 at 03:55:01 UTC, Meta wrote: The name validator_t is not idiomatic in D. Something like ValidatorFun should be preferred. Same for intReader_t; ReadIntFun is probably preferred, or even IntReader (but that would imply that it's a struct/class in my mind). Noted. Thanks. As for the actual use of partial, it's perfectly fine and idiomatic to use. Good. Now the questions is what should be the signature of the receiving functions if I'm going to pass the (double) curried function around? For example, considering the original piece of code, if I do alias partial!(partial!(readInt, "Enter an integer:"), ) ReaderFun; is the following a valid signature for `foo`, to which I'll pass a `ReaderFun`? void foo((int delegate() readerFun)
What are (dis)advantages of using pure and immutable by default?
It seems to me a good practice to mark all functions that I write as `pure` and define all the variables as `immutable`, unless there is a reason not to. I can see some serious advantages of this, most notable of which is minimum side-effect and predictability of the code. However I suppose it's going to impact the performance and memory footprint as well, though I have no idea how deep the impact will be. I'm pretty sure I'm not the first one to think about this; so what would you seasoned D'ers say?
Better unittest failure output
I am working on a simple project created with DUB[1]. When unit tests the output reads really cryptic to me; for example: $ dub test Generating test runner configuration '__test__library__' for 'library' (library). Target dunit 1.0.11 is up to date. Use --force to rebuild. Building d-etudes ~master configuration "__test__library__", build type unittest. Compiling using dmd... Linking... Running ./__test__library__ core.exception.AssertError@source/e002.d(111): unittest failure ./__test__library__(void detudes.e002.__unittest_fail(int)+0x28) [0x4bf508] ./__test__library__(void detudes.e002.__unittestL106_4()+0x17b) [0x4bf47b] ./__test__library__(void detudes.e002.__modtest()+0xe) [0x4bf48e] ./__test__library__(int core.runtime.runModuleUnitTests().__foreachbody2(object.ModuleInfo*)+0x34) [0x4d0d0c] ./__test__library__(int object.ModuleInfo.opApply(scope int delegate(object.ModuleInfo*)).__lambda2(immutable(object.ModuleInfo*))+0x1c) [0x4c1ab4] ./__test__library__(int rt.minfo.moduleinfos_apply(scope int delegate(immutable(object.ModuleInfo*))).__foreachbody2(ref rt.sections_elf_shared.DSO)+0x46) [0x4c7422] ./__test__library__(int rt.sections_elf_shared.DSO.opApply(scope int delegate(ref rt.sections_elf_shared.DSO))+0x41) [0x4c7499] ./__test__library__(int rt.minfo.moduleinfos_apply(scope int delegate(immutable(object.ModuleInfo*)))+0x20) [0x4c73bc] ./__test__library__(int object.ModuleInfo.opApply(scope int delegate(object.ModuleInfo*))+0x20) [0x4c1a90] ./__test__library__(runModuleUnitTests+0x98) [0x4d0bd8] ./__test__library__(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()+0x17) [0x4c4147] ./__test__library__(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())+0x2a) [0x4c40fa] ./__test__library__(_d_run_main+0x1d2) [0x4c407a] ./__test__library__(main+0x20) [0x48a968] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7f1f751d9ec5] Error executing command test: Program exited with code 1 It is almost impossible for me to comprehend anything useful out of this, except that, well, the tests have failed :-) Is there any compiler switch, argument to `assert` or trick to make `unittest` output more helpful messages when failing? [1] https://github.com/bahmanm/d-etudes
Re: Better unittest failure output
On Monday, 7 September 2015 at 12:16:14 UTC, anonymous wrote: On Monday 07 September 2015 14:12, Bahman Movaqar wrote: Thanks. This is indeed helpful. OT but where can I view the documentation for `unittest` and `assert`? unittest: http://dlang.org/unittest.html assert: http://dlang.org/expression.html#AssertExpression (I don't know why it's considered an expression and not a statement.) Thanks.
Re: What are (dis)advantages of using pure and immutable by default?
On Monday, 7 September 2015 at 11:49:32 UTC, anonymous wrote: void f(int a) {} void g(int* a) {} void main() { int xm; immutable int xi; f(xm); /* ok, obviously */ f(xi); /* ok */ int* ym = immutable int* yi = g(ym); /* ok, obviously */ g(yi); /* doesn't compile */ } f(xi) is ok because when passing an int or an immutable(int), it's copied completely. So the f cannot possibly mutate the original immutable variable xi. g(yi) is not ok, because when passing an int* or an immutable(int*), only the pointer is copied. So g could dereference yi and mutate the referenced immutable variable xi. The same applies to other forms of references: classes, ref parameters, arrays. Thanks for the explanation. So from what I can gather, `immutable`, apart from possible compiler-level optimisations, is mainly there to help the programmer catch otherwise runtime errors at compile time. This is nice. Indeed very helpful in a language when one deals with pointers and references.
Re: What are (dis)advantages of using pure and immutable by default?
On Monday, 7 September 2015 at 10:55:13 UTC, anonymous wrote: On Monday 07 September 2015 12:40, Bahman Movaqar wrote: I can see some serious advantages of this, most notable of which is minimum side-effect and predictability of the code. However I suppose it's going to impact the performance and memory footprint as well, though I have no idea how deep the impact will be. I don't see how merely marking things immutable/pure would affect performance negatively. They're just marks on the type. If anything, you could get a performance boost from the stricter guarantees. But realistically, there won't be a difference. Just "marks", eh? I was under the impression that when a variable, that is declared as `immutable`, is passed to a function, a copy of the value is passed. However based on "marks" I can imagine that since the data is marked as `immutable` only a reference is passed; and the compiler guarantees that what is referenced to never changes. Am I right? If you change your algorithms to avoid mutable/impure, then you may see worse performance than if you made use of them. But I suppose that would be "a reason not to" mark everything immutable/pure. True. Nowadays that more algorithms are designed with parallelism and distribution in mind, though, I believe mutating values and impure functions, at least in certain domains, will cease to exist.
Re: Better unittest failure output
On Monday, 7 September 2015 at 12:06:09 UTC, anonymous wrote: On Monday 07 September 2015 13:57, Bahman Movaqar wrote: $ dub test [...] core.exception.AssertError@source/e002.d(111): unittest failure [...] From that one line I left intact above, you should also be able to figure out that it's the test in source/e002.d, line 111 that failed. True. That I had already figured out. I was actually hoping for something like Groovy's assert messages[1], if possible. Is there any compiler switch, argument to `assert` or trick to make `unittest` output more helpful messages when failing? You can pass a custom message as a second argument to assert: assert(condition, "message goes here"); Thanks. This is indeed helpful. OT but where can I view the documentation for `unittest` and `assert`? [1] http://docs.groovy-lang.org/next/html/documentation/core-testing-guide.html#_power_assertions
Chaining struct method invocations
I need some help understand the behaviour of my code[1]. Specifically I have trouble with `add` method on line 79. My impression is that since it returns `this`, multiple invocations can be chained like `obj.add(X).add(Y).add(Z)`. However the test on line 92 fails and if I do a `writeln`, only "p1" and "p2" records show up. What am I missing here? Thanks in advance. [1] https://github.com/bahmanm/d-etudes/blob/master/source/e002/models.d
Re: Chaining struct method invocations
On Monday, 7 September 2015 at 14:54:04 UTC, Jacob Carlborg wrote: On 2015-09-07 16:44, Bahman Movaqar wrote: Does this mean that in the following piece of code, what is passed to `add` is actually a copy of `rec1`? auto rec1 = SalesRecord("p10", 1.0, 10); coll.add(rec1); Yes. structs have value semantics. If you want reference semantics you might want to use a class instead. Actually I like the value semantics very much. I think I'm going to stick to `structs` for as much as possible :-)
Re: Chaining struct method invocations
On Monday, 7 September 2015 at 14:26:57 UTC, mzf wrote: On Monday, 7 September 2015 at 14:12:25 UTC, Bahman Movaqar wrote: struct is a value type,you can convert to ref type by "ref": struct Test { int a; Test add1() { a++; return this; } ref Test add2() { a++; return this; } } Test t1; t1.add1.add1; writeln(t1.a);//1 Test t2; t2.add2.add2; writeln(t2.a);//2 Thanks. I was afraid I had to resort to using pointers to achieve this!
Re: Chaining struct method invocations
On Monday, 7 September 2015 at 14:28:06 UTC, Namespace wrote: On Monday, 7 September 2015 at 14:12:25 UTC, Bahman Movaqar wrote: Structs are value types and therefore you return only a copy currently. Does this mean that in the following piece of code, what is passed to `add` is actually a copy of `rec1`? auto rec1 = SalesRecord("p10", 1.0, 10); coll.add(rec1);
How To: Passing curried functions around
I'm just learning D, so please bear with me if I'm asking something naive. Consider the following code skeleton: // in part A of the application... // - alias bool function(int n) validator_t; bool isEven(int n) { ... } bool isPrime(int n) { ... } /** * keeps asking for an int from the user until it passes * the given validator. */ int readInt(string prompt, validator_t validator) { ... } // in part B of the application which knows nothing about part A // - /** * does something that involves reading an integer from input */ void foo(intReader_t reader) { ... } I'm trying to pass curried versions of `readInt` to `foo`. Obviously, I don't wish part B to know about the details of a "reader" nor I'd like to pass `prompt` and `validator` to `foo` (this really doesn't concern `foo` at all). I see that the solution is using `partial` from `std.functional`; for example: partial!(partial!(readInt, "Enter an integer:"), ) However, I'm not sure if this is correct (let alone idiomatic!) and even if this is the correct way of currying `readInt`, what should be the signature of `foo`? I'd appreciate any help/hint on this.
Re: How To: Passing curried functions around
On Sunday, 6 September 2015 at 19:22:41 UTC, welkam wrote: I dont know much about functional programming, but what stops you defining int readInt(string prompt, validator_t validator) { ... } as a free standing function and just call it from both parts of your code? What is the benefit of indirection that you create when passing function pointer? Nothing specific to FP here. I simply do not want to share the details of reading an integer with part B. Imagine the same thing done with classes: // part A // class IntReader { string prompt; validator_t validator; int read() const { ... } } // part B // auto ir = new IntReader(...); foo(ir); This way, all `foo` needs to know is calling `read` to get an integer. I'm trying to achieve the same thing here with functions, if possible.