Re: Find homography in D?
On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote: Hi, Someone can point me to a D implementation of the classical OpenCV find homography matrix? Thank you, Paolo Something I wrote awhile ago... ``` import kaleidic.lubeck : svd; import gfm.math; import mir.ndslice : sliced; auto generateTransformationArray(int[] p) { return generateTransformationArray(p[0],p[1],p[2],p[3]); } auto generateTransformationArray(int x, int y, int x_, int y_) { return [-x, -y, -1, 0, 0, 0, x*x_, y*x_, x_, 0, 0, 0, -x, -y, -1, x*y_, y*y_, y_]; } auto transformCoor (mat3d mat, vec3d vec) { auto res = mat * vec; return res / res[2]; } auto findHomography (int[][] correspondances) { auto a = correspondances .map!(a => a.generateTransformationArray) .joiner .array .sliced(8,9); auto r = a.svd; auto homog = r.vt.back; return mat3d(homog.map!(a => a/homog.back).array); } ```
profiling vibe
I can't seem to be able to use `--profile` with vibe: ```shell dub init -t vibe.d dub build --build=profile ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable Error: warnings are treated as errors Use -wi if you wish to treat warnings only as informational. ``` I've tried using `buildRequirements "allowWarnings"`, but still the same. Jordan
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Friday, 19 January 2024 at 08:57:40 UTC, Renato wrote: Do you know why the whole thread seems to have disappeared?? There's a lot of good stuff in the thread, it would be a huge shame to lose all that! I agree! Thanks for posting your benchmarks, I thought your whole benching setup was pretty good, and learnt alot from your code and the resulting contributions in the thread and others. Jordan
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Saturday, 13 January 2024 at 11:03:42 UTC, Renato wrote: I like to use a phone encoding problem to determine the strenghtness and weaknesses of programming languages because this problem is easy enough I can write solutions in any language in a few hours, but complex enough to exercise lots of interesting parts of the language. [...] Hello Renato, This seems to be quite a lot of calls: ``` Timer frequency unknown, Times are in Megaticks Num TreeFuncPer CallsTimeTimeCall 1920496437613756 0 pure nothrow ref @trusted immutable(char)[][] core.internal.array.appending._d_arrayappendcTX!(immutable(char)[][], immutable(char)[])._d_arrayappendcTX(scope return ref immutable(char)[][], ulong) 1920492489573474 0 @safe void dencoder.printTranslations(immutable(char)[][][dencoder.Key], dencoder.ISolutionHandler, immutable(char)[], immutable(char)[], immutable(char)[][]) ``` This is when using the `words-quarter.txt` input (the `dictionary.txt` input seems to finish much faster, although still slower than `java`/`rust`). I also used only 100 phone numbers as input. My final observation is that `words-quarter.txt` contains some 1-letter inputs, (for example, `i` or `m`)...this may result in a large number of encoding permutations, which may explain the high number of recursion calls? Jordan
Re: Python <==> d call both ways example (with PyD and autowrap)?
On Wednesday, 22 June 2022 at 16:02:00 UTC, mw wrote: Hi, I know with PyD, D can call Python, and with autowrap, Python can call a D .dll, I'm just wondering if someone can show an example that Python <==> d can call both ways? esp. show passing D objects to Python and then call its member function there, and vice versa. Thanks. When I did something like this, I used this as my inspiration: https://github.com/ariovistus/pyd/tree/master/examples/testdll So, I used PyD to supply D objects and read Python data also. Thanks, Jordan
Re: writeln the struct from the alis this Example from the home page
On Thursday, 18 November 2021 at 16:08:22 UTC, Paul Backus wrote: On Thursday, 18 November 2021 at 13:51:42 UTC, Martin Tschierschke wrote: [...] You can define a `toString` method, like this: ```d string toString() { import std.conv; return p.to!string; } ``` You can find more information about `toString` in the documentation here: https://dlang.org/phobos/std_format_write.html By the way, the reason your original version does not work is that `p` is `private`, so `writeln` cannot access it. If you change `p` to be `public`, it will work without a `toString` method. I thought private was to the module/file, not class/struct? Jordan
Re: is it possible to sort a float range ?
On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven Schveighoffer wrote: On 6/23/21 6:30 PM, Jordan Wilson wrote: On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote: [...] ```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```. Use the `release` method: ```d return lnumRange.sort!(...).release; ``` -Steve Wow...learn something new every day, cheers! Jordan
Re: is it possible to sort a float range ?
On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote: Please, look for the line marked +++ This is a structure with a public property returning a (still unsorted) range built on-the-fly from already-set properties, a basic range from a to z with n step where some specific values can be added in-between. The range is a float which I am currently using for currency (horrible) and later plan to move it to decimal 10 or the like. [...] ```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```.
Re: DUB doesn't seem to respect my config, am I doing something wrong?
On Saturday, 22 May 2021 at 20:28:56 UTC, rempas wrote: I've read the documentation about DUB's config (I'm using the SDL format) and it seems that DUB completely ignores my config. My config file is: ``` name "test" description "Testing dub" authors "rempas" copyright "Copyright © 2021, rempas" license "AGPL-3.0" compiler "ldc2" configuration "development" { platforms "linux" build "dubug" compiler "ldc2" targetType "executable" } configuration "release" { platforms "linux" dflags "-Oz" platform="/bin/ldc2" build "release" compiler "ldc2" targetType "executable" } ``` I'm compiling using `dub --config=development` and I'm getting the following line: `Performing "debug" build using /usr/bin/dmd for x86_64`. The same exactly happens when I'm trying to do the release config. If I disable the `targetType` option, it seems that it's creating a library and I can also manually change the compiler and the build-type so I don't know what's going on Ignoring the "dubug" typo...normally, I think you pass compiler values directly to dub via the ```--compiler``` flag. For example: ```shell dub --config=development --compiler=ldc2 ``` Note: you can also pass "debug" and "release" builds (among others), like so: ```shell dub -b "debug" --compiler=ldc2 ``` Passing in the compiler allows any end user building your code to use whatever compiler they want. Otherwise, something like ```toolchainRequirements dmd="no" ldc=">=1.21.0"``` may achieve what you want. Thanks, Jordan
Re: Recommendations on avoiding range pipeline type hell
On Sunday, 16 May 2021 at 09:55:31 UTC, Chris Piker wrote: On Sunday, 16 May 2021 at 09:17:47 UTC, Jordan Wilson wrote: Another example: ```d auto r = [iota(1,10).map!(a => a.to!int),iota(1,10).map!(a => a.to!int)]; # compile error ``` Hi Jordan Nice succinct example. Thanks for looking at the code :) So, honest question. Does it strike you as odd that the exact same range definition is considered to be two different types? Maybe that's eminently reasonable to those with deep knowledge, but it seems crazy to a new D programmer. It breaks a general assumption about programming when copying and pasting a definition yields two things that aren't the same type. (except in rare cases like SQL where null != null.) On a side note, I appreciate that `.array` solves the problem, but I'm writing pipelines that are supposed to work on arbitrarily long data sets (> 1.4 TB is not uncommon). There are those far more learned than me that could help explain. But in short, yes, it did take a little getting used to it - I would recommend looking at Voldemort types for D. Ironically, use of Voldemort types and range-based programming is what helps me perform large data processing. Jordan
Re: Recommendations on avoiding range pipeline type hell
On Sunday, 16 May 2021 at 07:20:52 UTC, Chris Piker wrote: On Saturday, 15 May 2021 at 14:05:34 UTC, Paul Backus wrote: If you post your code (or at least a self-contained subset of it) someone can probably help you figure out where you're running into trouble. The error messages by themselves do not provide enough information--all I can say from them is, "you must be doing something wrong." I just tacked on `.array` in the the unittest and moved on for now, but for those who may be interested in the "equivalent but not equivalent" dmd error message mentioned above, the code is up on github. To trigger the error message: ```bash git clone g...@github.com:das-developers/das2D.git cd das2D rdmd -unittest --main das2/range.d # This works ``` In file `das2/range.d`, comment out lines 550 & 553 and uncomment lines 557 & 558 to get alternate definitions of `coarse_recs` and `fine_recs` then run rdmd again: ```bash rdmd -unittest --main das2/range.d # No longer works ``` In addition to the issue mentioned above, comments on any style issues, best practices or design choices are invited. By the way the writeln calls in the unittests just temporary. Essentially, `dr_fine` and `dr_coarse` are different types. For example: ```bash echo 'import std; void main() { auto a = [a,"test"]; }' | dmd -run - # your error ``` Another example: ```d auto r = [iota(1,10).map!(a => a.to!int),iota(1,10).map!(a => a.to!int)]; # compile error ``` Using ```.array``` on both of the elements of r will compile. Thanks, Jordan
Re: Local library with dub
On Wednesday, 21 April 2021 at 15:07:25 UTC, JG wrote: On Wednesday, 21 April 2021 at 00:39:41 UTC, Mike Parker wrote: On Tuesday, 20 April 2021 at 18:43:28 UTC, JG wrote: This still leaves open the question of how to include a version of such a library in another project via dub. Execute `dub add-local` followed by the path to the project's root directory (the directory containing the `dub.json/sdl`) and a version number in semver format. ``` dub add-local path 0.1.0 ``` Then you can use the package just as you would any other dub dependency. Thanks. I suppose this means that if you want to able to use multiple versions you have to keep each version in a separate directory and add them individually, and there is no way of being able to get the appropriate version from say a git repository? You can specify git repos as dependencies, if this helps. https://dlang.org/changelog/2.094.0.html#git-paths Jordan
Re: Contributing CDF bindings to Deimos
On Thursday, 25 March 2021 at 04:00:33 UTC, Chris Piker wrote: On Tuesday, 23 March 2021 at 05:54:13 UTC, mw wrote: [...] Okay, that's done. The repo https://github.com/das-developers/deimos.cdf and package https://code.dlang.org/packages/cdf have been drafted and tested on Linux, I'm about to test on Windows and MacOS. As an aside, software developers at NASA Goddard have now heard of D which is nice. They were pleased to see that it was supported by gcc. (Hat tip to the GDC team) I've attempted to follow all guidelines as best I understood them, but this is my first package. It likely has some style and functionality issues. Is there a peer review stage to this process that is triggered automatically or could be requested? Nice one. I've used HDF5/NetCDF, will have to check out and see what CDF offers. Jordan
Re: Best way to learn 2d games with D?
On Sunday, 15 March 2020 at 17:58:58 UTC, Steven Schveighoffer wrote: I want to try and learn how to write 2d games. I'd prefer to do it with D. I've found a ton of tutorials on learning 2d gaming with other languages. Is there a place to look that uses D for learning? Should I just start with another language and then migrate to D later? Anyone recommend any specific tutorial/book? -Steve I'm on a similar journey myself, I'll list my findings, maybe it could be useful for you. I decided on a game programming library. I mostly looked at SFML and Allegro, and found both to have good bindings available in D, and good documentation, and got minimal examples working with both. I went with SFML, simply because there was a book written specifically about writing a game in SFML. I didn't see any such books for Allegro (although there are plenty of tutorials/articles). I learnt about the "game loop". Bauss touched on it in his post, and I'm sure there are a lot of tutorials on it. I specifically learnt about it from the first few chapters of the SFML Game Development book. I learnt about game design. In doing so, I came across Entity-Component-System design pattern. I decided to use this pattern, for no other reason than to try something other than OOP. I found these links useful: https://medium.com/ingeniouslysimple/entities-components-and-systems-89c31464240d https://gameprogrammingpatterns.com/component.html https://www.richardlord.net/blog/ecs/what-is-an-entity-framework.html I started writing a game, using the derelict-sfml2 as my game library (again, I found the allegro library to be good too), and entitysysd to provide the ECS framework (there are a few ECS written in D available). Are they the best choices? Is SFML technically limited? Will I cope with ECS beyound the toy game example? No idea. But I'm having a lot of fun, which I think for a hobby project, is a fairly good measure of success ;-) Jordan
Re: SQLite 3 support?
On Wednesday, 26 February 2020 at 20:06:20 UTC, mark wrote: There seems to be some support for SQLite 3 in std. lib. etc when looking at the stable docs: https://dlang.org/phobos/etc_c_sqlite3.html But this isn't visible when looking at stable (ddox). Is this the best SQLite 3 library to use or is a third-party library best? For example https://github.com/biozic/d2sqlite3 I use d2sqlite3 regularly, no problems at all with it. I have no experience with the std. lib one. Jordan
Re: Is removing elements of AA in foreach loop safe?
On Thursday, 29 August 2019 at 10:11:58 UTC, berni wrote: Iterating of some structure and removing elements thereby is always errorprone and should be avoided. But: In case of AA, I've got the feeling, that it might be safe: foreach (k,v;ways) if (v.empty) ways.remove(k); Do you agree? Or is there a better way to achieve this? This should work, due to the keys property returning a dynamic array: foreach (k; ways.keys) { if (ways[k].empty) ways.remove(k); } Jordan
Re: Function called twice
On Friday, 2 August 2019 at 22:35:53 UTC, Adam D. Ruppe wrote: On Friday, 2 August 2019 at 21:44:28 UTC, Jordan Wilson wrote: // outputs 1 2 2 3 z.map!(a => tuple!("number","iseven")(a, a.isEven)) .filter!(a => a.iseven) .array; I *think* what's happening here is first it calls map() first going into the filter... then it gets called again when it is being evaluated for the array. So like basically consider if you had: if(filter(a()) array ~= a(); that kind of thing. I think anyway, I'm not entirely sure but it fits what I can see happening here. but idk why it is actually doing this in the phobos implementation In my real-world case "isEven" is a long running function. I'll put an .array after the map and see if it makes a difference. Thanks, Jordan
Function called twice
Hello, I don't quite understand why isEven is called twice in the 2nd example? auto isEven(int n) { n.writeln; return (n % 2) == 0; } void main() { auto z = [1,2,3]; // outputs 1 2 3 z.map!(a => tuple!("number")(a)) .filter!(a => a.number.isEven) .array; // outputs 1 2 2 3 z.map!(a => tuple!("number","iseven")(a, a.isEven)) .filter!(a => a.iseven) .array; return; } Thanks, Jordan
Re: Finding Max Value of Column in Multi-Dimesional Array
On Friday, 5 July 2019 at 00:54:15 UTC, Samir wrote: Is there a cleaner way of finding the maximum value of say the third column in a multi-dimensional array than this? int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]]; writeln([p[0][2], p[1][2], p[2][2]].max); I've tried the following writeln([0, 1, 2].map!(p[a][2]).max); but get an "Error: undefined identifier a" error. I know there doesn't seem to be much of a difference between two examples but my real-world array is more complex which is why I'm looking for a more scalable option. Thanks Samir p.map!(a => a[2]).maxElement.writeln; // 5 p.map!"a[2]".maxElement.writeln; // 5 Or, modifying your example: writeln([0,1,2].map!(a => p[a][2]).maxElement; Thanks, Jordan
Re: How to break from parallel foreach?
On Tuesday, 26 February 2019 at 19:58:24 UTC, Andrey wrote: Hello, How to break from parallel foreach? More general question - how to control such loop? A basic way would be to use a flag: shared stopWork=false; foreach (wordBag; wordBags.parallel) { if (!stopWork) { // do work if (wordBag.canFind("myword")) stopWork=true } } I'd say it's probably not an elegant solution to "break" from parallel forloops, but that's up to you to decide. Jordan
Re: How can I walk the list in a RegexMatch backwards?
On Sunday, 3 February 2019 at 18:07:13 UTC, Chris Bare wrote: auto matches = matchAll(str, searchRegex); foreach (m; matches) // this walks the list forward I tried: foreach_reverse (m; matches) foreach (m; reverse (matches)) foreach (m; retro (matches)) and they all failed to compile. I also tried to index matches (matches[i]) but that does not work either. matchAll is a forward range, whereas retro requires a bi-directional range. So using the array function should work: foreach (m; matches.array.retro) Jordan
Re: Access program args outside of main
On Wednesday, 17 October 2018 at 22:37:53 UTC, Stanislav Blinov wrote: On Wednesday, 17 October 2018 at 22:30:31 UTC, Jordan Wilson wrote: Ideally, I'd check args before I take the time to load up data. https://dlang.org/phobos/core_runtime.html#.Runtime Here I was looking through std...thanks mate. Jordan
Access program args outside of main
Hello, Is there a way to access command line arguments outside of main? // main.d module main; import data; void main(string args[]) { } // data.d module data immutable programData; static this() { // read in data } Ideally, I'd check args before I take the time to load up data. Thanks, Jordan
Re: Windows 64-bit import library
On Friday, 20 July 2018 at 12:03:20 UTC, evilrat wrote: On Friday, 20 July 2018 at 04:31:38 UTC, Jordan Wilson wrote: On Friday, 20 July 2018 at 01:34:39 UTC, Mike Parker wrote: On Thursday, 19 July 2018 at 21:43:35 UTC, Jordan Wilson wrote: Is there any way I can generate the appropriate lib? Else I think I'll need to get hold of the proper import libs that come with the Lua distribution. Lua is extremely easy to build. That will generate the import lib for you. I don't have MSVC, so I built it using mingw, which generated a .a lib. I shall google some more, as I understand it DMD -m64 uses Mingw libs as a fall back when MSVC not found, I compiled Lua using mingw, I can't be too much further away from being able to link in a 64-bit lua import lib in a 64-bit DMD compiled program... what about passing your .def file directly with /DEF:your.def linker switch? more info https://msdn.microsoft.com/en-us/library/34c30xs1.aspx Thanks, I tried your suggestion, but received: lld-link: warning: : undefined symbol: luaL_newstate lld-link: warning: : undefined symbol: luaL_addlstring lld-link: warning: : undefined symbol: luaL_addstring lld-link: warning: : undefined symbol: luaL_addvalue lld-link: warning: : undefined symbol: luaL_argerror lld-link: warning: : undefined symbol: luaL_buffinit etc. I think I'll just have to obtain the lib from the LuaBinaries distribution. Thanks, Jordan
Re: Windows 64-bit import library
On Friday, 20 July 2018 at 05:12:05 UTC, Mike Parker wrote: On Friday, 20 July 2018 at 04:31:38 UTC, Jordan Wilson wrote: I don't have MSVC, so I built it using mingw, which generated a .a lib. I shall google some more, as I understand it DMD -m64 uses Mingw libs as a fall back when MSVC not found, I compiled Lua using mingw, I can't be too much further away from being able to link in a 64-bit lua import lib in a 64-bit DMD compiled program... In that case, you may be better off using the DerelictLua binding [1] so that you can avoid the link-time dependency and just load the Lua DLL manually at runtime via `DerelictLua.load` [2]. Then it doesn't matter which compiler the DLL was compiled with or which toolchain you use to compile your app. Version 2.0.0-beta.2 (master and 2.0 branches) binds to Lua 5.3 (don't let the beta tag scare you -- it's stable). If you need Lua 5.2 instead, version 1.3.0 binds to it. [1] https://code.dlang.org/packages/derelict-lua [2] https://github.com/DerelictOrg/DerelictLua Ah I think you have indirectly reminded me what the problem could be, the luaD wrapper that's available is for 5.1 I think (I'm trying to link lua 5.3). Your binding did work quite well, but I think I'll try again using lua 5.1, so I can keep using luaD. Thanks, Jordan
Re: Windows 64-bit import library
On Friday, 20 July 2018 at 01:34:39 UTC, Mike Parker wrote: On Thursday, 19 July 2018 at 21:43:35 UTC, Jordan Wilson wrote: Is there any way I can generate the appropriate lib? Else I think I'll need to get hold of the proper import libs that come with the Lua distribution. Lua is extremely easy to build. That will generate the import lib for you. I don't have MSVC, so I built it using mingw, which generated a .a lib. I shall google some more, as I understand it DMD -m64 uses Mingw libs as a fall back when MSVC not found, I compiled Lua using mingw, I can't be too much further away from being able to link in a 64-bit lua import lib in a 64-bit DMD compiled program...
Windows 64-bit import library
I'm trying to create an import library from a dll (in this case, a Lua dll). Using dumpbin, I end up with a .def file: EXPORTS luaL_addlstring luaL_addstring luaL_addvalue luaL_argerror luaL_buffinit ... I then use MS lib tool to generate a lib file: lib /def:lua53.def /out:lua53.lib /machine:x64 I'm able to link the lib without errors (i.e. no "not valid lib" errors or anything), but that's as far as I get...any attempt to call functions results in: undefined symbol: luaL_newstate etc. Is there any way I can generate the appropriate lib? Else I think I'll need to get hold of the proper import libs that come with the Lua distribution. Thanks, Jordan
Re: Nullable!T with T of class type
On Thursday, 28 June 2018 at 19:22:38 UTC, Jonathan M Davis wrote: On Thursday, June 28, 2018 18:10:07 kdevel via Digitalmars-d-learn wrote: On Tuesday, 26 June 2018 at 21:54:49 UTC, Jonathan M Davis wrote: > [H]onestly, I don't understand why folks keep trying to put > nullable types in Nullable in non-generic code. How do you signify that a struct member of class type is optional? Structs aren't nullable, so wrapping them in a Nullable makes perfect sense. Whether they happen to be on the stack or members of another type is irrelevant to that. It's wrapping types like pointers and class references in a Nullable that's an odd thing to do - the types where someone might ask why the extra bool is necessary in the Nullable. Wrapping them in a Nullable makes sense in generic code, because the code isn't written specifically for them, but something like Nullable!MyClass in non-generic code is pointless IMHO, because a class reference is already nullable. - Jonathan M Davis Reading inpput from a csv file, and the value could either be blank, na, or numeric. Nullable!MyClass could be used to represent 3 states in your programming logic. I'm not saying this is the best way to represent ternary states, but it's not unreasonable. Jordan Wilson
Re: Zip vs Enumerate
On Wednesday, 20 June 2018 at 05:49:15 UTC, Dukc wrote: On Wednesday, 20 June 2018 at 03:44:58 UTC, Jordan Wilson wrote: Is there anything I can do to improve zip, before I go ahead and change to the faster but slightly less readable enumerate? The problem might be that zip checks both arrays for empty during each step, enumerate only the first one. Try appending takeExactly(1000) on the result of zip. It might be even faster than enumerate. takeExactly didn't change the timings at all. I did write a rough zip function that took advantage of random access inputs and didn't need to account for different stopping policies: auto myZip(R1,R2) (R1 r1, R2 r2) { struct MyZip(R1,R2) { size_t index=0; R1 rng1; R2 rng2; size_t length; this (R1 r1, R2 r2) { rng1=r1; rng2=r2; index=0; length=r1.length; } auto empty() { return index==length; } auto front() { return tuple(rng1[index],rng2[index]); } void popFront() { index++; } } return MyZip!(R1,R2)(r1,r2); } This ended up being 40% faster than normal zip, both DMD 32/64. I briefly tested with LDC and didn't notice any difference, which I thought was weird, but didn't have time to investigate further. That fact that zip is slower is not bad, as it provides far more flexibility, different stopping policies, all types of ranges. What is interesting (TBC) is the fact that it's only noticeably slower using DMD. Jordan
Zip vs Enumerate
Hello, Idiomatically, I make use of zip, however, when looking to speed up my program, notice that using enumerate leads to a 20-30% improvement: void main(){ auto x = iota(1_000).array; auto y = iota(1_000).array; auto func1() { return zip(x,y).map!(a => a[0]+a[1]) .array; } auto func2() { return x.enumerate .map!(a => a.value + y[a.index]) .array; } assert(func1.equal(func2)); import std.datetime.stopwatch; auto r = benchmark!(func1, func2)(10_000); // r[0] approx 1794 ms // r[1] approx 1295 ms } Is there anything I can do to improve zip, before I go ahead and change to the faster but slightly less readable enumerate? In my particular case, all ranges that I zip are of the same length, but not sure how I can leverage that information. Thanks, Jordan
Re: Sense check: construction / deconstruction
On Wednesday, 25 April 2018 at 13:52:16 UTC, Steven Schveighoffer wrote: [...] Great, thanks for you help Steve, I'll have a think about how I want to structure things. Jordan
Re: Sense check: construction / deconstruction
On Tuesday, 24 April 2018 at 23:49:14 UTC, Steven Schveighoffer wrote: What you are missing is that Database is pass-by-value, not a class. So when you include it directly in a class like you did in A, then when A's destructor is called, db's destructor is called. Since in the first case, a is being destroyed by the GC, you get the error. Ok, this makes sense. In the second case (b), you aren't including the db by value, so no destructor is called from the GC. But this is dangerous, because db stops existing after main exits, but b continues to exist in the GC, so this is a dangling pointer. If I set the pointer to null, before (b) is collected, would that work? In the third case, scoped specifically destroys c when main exits, and you are not in the GC at that point. What the error message is telling you is you should manually clean up the database directly instead of leaving it to the GC. What is the correct path? probably the scoped!A version. Though I'm not sure what making copies of the database does in that library. -Steve Ok I'll need to read the docs on scoped I think, but I think I understand. If I wanted db to be persistent, but have temporary objects reference db without triggering GC collection of the db, you would use scoped? Or is this a situation where it's better to pass the db in function calls to objects rather than set as a member of these objects?
Sense check: construction / deconstruction
I have the following code: import std.stdio; import std.typecons; import d2sqlite3; class A { Database db; this ( Database d) { db = d; } } class B { Database* db; this ( Database* d) { db = d; } } void main() { auto db = Database(":memory:"); auto a = new A(db); // gives message: // Error: clean-up of Database incorrectly // depends on destructors called by the GC auto b = new B(&db); // no message auto c = scoped!A(db); // no message } Assumption 1: "a" gives me an error message due to the fact that proper clean up of db depends on a being collected by the GC, and this behavior is being dis-allowed through use of the idiom https://p0nce.github.io/d-idioms/#GC-proof-resource-class? The relevant function calling the error message is: void ensureNotInGC(T)(string info = null) nothrow { import core.exception : InvalidMemoryOperationError; try { import core.memory : GC; cast(void) GC.malloc(1); return; } catch(InvalidMemoryOperationError e) { // error message here } } Assumption 2: "b" gives me no error messages because the class B uses pointers, which moves it from relying on GC, to being manually free? Assumption 3: "c" gives me no error messages because...well, I don't really understand why, maybe because c is in the same scope as db? Thanks, Jordan
Re: Better way to append to array than ~= ?
On Tuesday, 3 April 2018 at 19:02:25 UTC, Vladimirs Nordholm wrote: Hello people. I currently have a function which multiple times per second takes in arguments, and appends the argument as my special type. The following code should explain what I do more properly: struct MySpecialType { char c; } auto foo(Args...)(Args args) { MySpecialType[] bar; foreach(ref arg; args) { static if(is(typeof(arg) == MySpecialType)) { bar ~= arg; } else { foreach(c; to!string(arg)) { bar ~= MySpecialType(c); } } } // do more stuff } Now, from my trace.log, some of the topmost things on the timing list are `std.array.Appender!(immutable(char).stuff>`. I also remember reading some years ago that ~= isn't optimal for speed. So my question is: Is there a better and/or faster way of doing this, or is this the best approach? I believe you are right to question the ~= in regards to performance. So, what I would do is replace this loop: foreach(c; to!string(arg)) { bar ~= MySpecialType(c); } with this one liner: bar ~= arg.map!(a => MySpecialType(a.to!char)).array; To my mind, you replace multiple appends with just the one append (to be fair, I don't know what the .array is doing internally, but I'm sure whatever it does is nice and optimised). Jordan
Re: cannot access frame of function
On Monday, 18 September 2017 at 21:58:39 UTC, Alex wrote: On Monday, 18 September 2017 at 18:49:54 UTC, ag0aep6g wrote: Doesn't work for me. This still fails compilation with the same error: import std.algorithm.iteration : sum, cumulativeFold; void main() { double[5] a; auto asum = 1.23; auto jProbs = a[].cumulativeFold!((a, b) => (a + b)/asum); } So, this is a bug, isn't it? I assume, I should file it then... I have this same issue. Anyone have any thoughts on a workaround? For example, my attempt at an exponential moving average doesn't compile: auto ema(Range,T) (Range rng, int period, T seed) { return rng.cumulativeFold!((a,b) => a+(2.0/(period+1))*(b-a))(seed.to!double); } So I ended up with this: auto ema(Range,T) (Range rng, int period, T seed) { struct EMA(Range) { double currentValue; double weighting; Range rng; this (Range r, int p, double s) { currentValue = s; weighting = 2.0 / (p+1); rng = r; } auto front() { return currentValue; } auto popFront() { rng.popFront; if (!rng.empty){ currentValue += (rng.front - currentValue)*weighting; } } auto empty() { return rng.empty; } } return EMA!Range(rng,period,seed.to!double); } Thanks, Jordan
Re: Understanding slide
On Thursday, 22 March 2018 at 03:58:35 UTC, Seb wrote: On Thursday, 22 March 2018 at 03:39:38 UTC, Jordan Wilson wrote: auto a = iota(5).slide!(Yes.withPartial)(3); auto b = iota(5).slide!(No.withPartial)(3); assert (a.equal(b)); The assert passes, but I would expect it to fail? They both are: [[0,1,2],[1,2,3],[2,3,4]] Thanks, Jordan See: https://forum.dlang.org/post/asocdlqaihkskiilr...@forum.dlang.org Ah I see. Apologies, I normally read the forums every day, must have just missed this one. Thanks
Understanding slide
auto a = iota(5).slide!(Yes.withPartial)(3); auto b = iota(5).slide!(No.withPartial)(3); assert (a.equal(b)); The assert passes, but I would expect it to fail? They both are: [[0,1,2],[1,2,3],[2,3,4]] Thanks, Jordan
Re: Date range iteration
On Monday, 12 March 2018 at 02:49:34 UTC, Jonathan M Davis wrote: On Monday, March 12, 2018 02:11:49 Jordan Wilson via Digitalmars-d-learn wrote: [...] Maybe iota should be made to work, but as present, it basically wants all three of the types it's given to be the same or implicitly convertible to a single type. It can't handle the step being a completely different type. [...] Yes I agree, a for loop for simple iteration is fine, but I'm sure there are cases where a date range would be quite useful, so the everyDuration tip is great, thanks! Jordan
Date range iteration
I wanted to iterate through a date range, so I initially tried: iota(Date(2016,1,1),Date(2018,1,1),dur!"days"(1)); That wouldn't compile, which is fair enough I guess. So I tried a for loop: for (auto i = Date(2016,1,1); i < Date(2018,1,1); i+=dur!"days"(1)){} That seemed to work fine, but I remember reading "for loops are bad" somewhere. So I looked for a range type mechanism, and I think it's this: foreach (i; Interval!Date (Date(2016,1,1),Date(2018,1,1)).fwdRange ( (a) { return a+dur!"days"(1); })){} My question is if the third way is the proper way of stepping through a period of time? It just seems quite complicated to me. Thanks, Jordan
Re: multithread/concurrency/parallel methods and performance
On Sunday, 18 February 2018 at 17:54:58 UTC, SrMordred wrote: I´m experimenting with threads and related recently. (i´m just started so may be some terrrible mistakes here) With this base work: foreach(i ; 0 .. SIZE) { results[i] = values1[i] * values2[i]; } and then with this 3 others methods: parallel, spawn and Threads. this was my results: _base : 456 ms and 479 us _parallel : 331 ms, 324 us, and 4 hnsecs _concurrency : 367 ms, 348 us, and 2 hnsecs _thread : 369 ms, 565 us, and 3 hnsecs (code here : https://run.dlang.io/is/2pdmmk ) All methods have minor speedup gains. I was expecting a lot more. Since I have 7 cores I expected like below 100ms. I´m not seeing false sharing in this case. or i'm wrong? If someone can expand on this, i'll be grateful. Thanks! It may be due to thread local storage: https://tour.dlang.org/tour/en/multithreading/thread-local-storage https://dlang.org/articles/migrate-to-shared.html I'm not sure though, as I don't know how your results array initialised. Jordan
Re: Derelict on Ubuntu with CODE::BLOCKS
On Sunday, 10 December 2017 at 16:50:10 UTC, RegeleIONESCU wrote: Hello! Please help me install and use Derelict on Ubuntu 16.04! [...] I use Code::Blocks myself, but doesn't have inbuilt dub support. This link should help: http://derelictorg.github.io/building/without-dub/ This will tell you how to build the appropriate Derelict bindings. Note: you'll still need to make sure the actual C/C++ library your trying to use in your D project is available as well. Jordan
Re: Array merge and sort
On Wednesday, 20 September 2017 at 06:29:17 UTC, Vino.B wrote: Hi All, My code output's the below so can any one help me on hot to merege all tese array and sort the same. Output : [ Tuple!(string, string)("C:\\Temp\\TEST1\\BACKUP\\DND1.pdf", "2017-Sep-06 16:06:42") ] [ Tuple!(string, string)("C:\\Temp\\TEST2\\EXPORT\\DND1.pdf", "2017-Sep-06 16:06:43")] [ Tuple!(string, string)("C:\\Temp\\TEST3\\PROD_TEAM\\DND1.pdf", "2017-Sep-06 16:06:43")] [ Tuple!(string, string)("C:\\Temp\\TEST4\\TEAM\\DND1.pdf", "2017-Sep-06 16:06:44") ] Code : foreach (string FFs; parallel(CleanDirlst[0 .. $], 1)) { MCresult.get ~= coCleanFiles(FFs.strip, Step); } foreach(i; MCresult.toRange) if (!i.empty) { writefln("%(%-(%-63s %s %)\n%)", i[]); } From, Vino.B I'm not sure what MCresult is, but perhaps using joiner can help you. import std.algorithm : joiner, sort; import std.range : array; import std.typecons : Tuple; auto data = [[Tuple!(string,string)("test4","1")], [Tuple!(string,string)("test3","4"),Tuple!(string,string)("test2","3")], [Tuple!(string,string)("test1","2")]]; auto sortedData = data.joiner .array .sort!((a,b) => a[0] < b[0]); sortedData.writeln; // outputs // [Tuple!(string, string)("test1", "2"), Tuple!(string, string)("test2", "3"), Tuple!(string, string)("test3", "4"), Tuple!(string, string)("test4", "1")] Jordan
Re: Rosetta Commatizing numbers
On Tuesday, 30 May 2017 at 10:54:49 UTC, Solomon E wrote: The earlier version of the page made D look more error prone than other languages, but short. Now my solution is as long as some of the other language's solutions, but it's well commented and tested, I think. Now I doubt any of the solutions in other languages are as correct or potentially useful or informative. Regardless to solution length...one place to make code a little shorter could be when you check for special prefix; maybe replace the two foreach loops? Something like: if (specials != null) { // There may be special prefixed formats that use different separators. // Any format with a longer prefix should override a shorter one. auto pairs = specials.byKeyValue .array .sort!((a,b) => a.key.length < b.key.length); auto preAnyDigit = matchNum.pre.stripRight('0'); pairs.filter!(a => preAnyDigit.length >= a.key.length) .filter!(a => a.key == preAnyDigit[$ - a.key.length .. $]) .each!(a => ins = a.value); } Jordan
Re: howto count lines - fast
On Tuesday, 30 May 2017 at 20:37:44 UTC, Jordan Wilson wrote: On Tuesday, 30 May 2017 at 20:02:38 UTC, Nitram wrote: After reading https://dlang.org/blog/2017/05/24/faster-command-line-tools-in-d/ , i was wondering how fast one can do a simple "wc -l" in D. So i made a couple short implementations and found myself confronted with slow results compared to "/usr/bin/wc -l". How would a implementation look like in D, which is fast? Not sure if this is the fastest, but anyway void main(){ import std.file : read; import std.conv : to; import std.algorithm : count; auto data = cast(ubyte[])read("somefile.txt"); auto lc = data.count('\n'.to!ubyte); } Jordan I should say, if you don't care about storing the data, File("somefile.txt","r").byLine.count is probably more idiomatic, and probably just as fast. Jordan
Re: howto count lines - fast
On Tuesday, 30 May 2017 at 20:02:38 UTC, Nitram wrote: After reading https://dlang.org/blog/2017/05/24/faster-command-line-tools-in-d/ , i was wondering how fast one can do a simple "wc -l" in D. So i made a couple short implementations and found myself confronted with slow results compared to "/usr/bin/wc -l". How would a implementation look like in D, which is fast? Not sure if this is the fastest, but anyway void main(){ import std.file : read; import std.conv : to; import std.algorithm : count; auto data = cast(ubyte[])read("somefile.txt"); auto lc = data.count('\n'.to!ubyte); } Jordan
Re: Out of memory error (even when using destroy())
On Friday, 26 May 2017 at 06:31:49 UTC, realhet wrote: Hi, I'm kinda new to the D language and I love it already. :D So far I haven't got any serious problems but this one seems like beyond me. import std.stdio; void main(){ foreach(i; 0..2000){ writeln(i); auto st = new ubyte[500_000_000]; destroy(st); //<-this doesnt matter } } Compiled with DMD 2.074.0 Win32 it produces the following output: 0 1 2 core.exception.OutOfMemoryError@src\core\exception.d(696): Memory allocation failed It doesn't matter that I call destroy() or not. This is ok because as I learned: destroy only calls the destructor and marks the memory block as unused. But I also learned that GC will start to collect when it run out of memory but in this time the following happens: 3x half GB of allocations and deallocations, and on the 4th the system runs out of the 2GB limit which is ok. At this point the GC already has 1.5GB of free memory but instead of using that, it returns a Memory Error. Why? Note: This is not a problem when I use smaller blocks (like 50MB). But I want to use large blocks, without making a slow wrapper that emulates a large block by using smaller GC allocated blocks. Is there a solution to this? Thank You! I believe the general solution would be to limit allocation within loops (given the issue Johnathan mentioned). This I think achieves the spirit of your code, but without the memory exception: ubyte[] st; foreach(i; 0..2000){ writeln(i); st.length=500_000_000; // auto = new ubyte[500_000_000]; st.length=0; // destory(st) st.assumeSafeAppend; // prevent allocation by assuming it's ok to overrwrite what's currently in st }
Re: How to avoid throwing an exceptions for a built-in function?
On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote: On Thu, May 11, 2017 at 05:55:03PM +, k-five via Digitalmars-d-learn wrote: On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote: > On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote: - > try this: > https://dlang.org/phobos/std_exception.html#ifThrown Worked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 } Keep in mind, though, that you should not do this in an inner loop if you care about performance, as throwing / catching exceptions will incur a performance hit. Outside of inner loops, though, it probably doesn't matter. T This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; Jordan
Re: first try
On Friday, 17 March 2017 at 00:35:32 UTC, Philip Miess wrote: This is my first 100+ line D program. https://gitlab.com/pmiess/101gamesDlangComputerGames/blob/master/ aceyducy.d Its a translation/refactor of aceyducy from 101 basic programs. Could someone look over it and see if I've made any glaring mistakes. Suggestions are welcome also. Thanks, Phil Hello Phil, I think there might be an issue with this function here: int inputInt ( string prompt){ int val ; writeln( prompt ~ "? "); string line; bool found = false; while ( !found ) { try { readf(" %d", &val); readln(); found = true; } catch (Exception e) { writeln( "? " ); } } return val; } I get an infinate loop if I put in something that's not convertible to an integer. I think what happens is that you catch the exception, the input still remains (presumably the buffer/range it's reading from hasn't had the chance to iterate through because of the thrown exception), and readf will always try and convert the input again. I'd probably rewrite it as this: int inputInt ( string prompt ){ import std.range : popBack; writeln( prompt ~ "? "); string line; while ((line = readln) !is null){ line.popBack; // remove line terminator try { return line.to!int; } catch (Exception e) { writeln ("? "); } } assert(0); } Thanks, Jordan
Re: I do not understand what the problem is in this code.
On Friday, 3 March 2017 at 03:11:24 UTC, steven kladitis wrote: void main() { import std.stdio, std.range, std.algorithm, std.string; const pieces = "KQRrBbNN"; alias I = indexOf; auto starts = permutations(pieces.dup).filter!(p => I(p, 'B') % 2 != I(p, 'b') % 2 && // Bishop constraint. // King constraint. ((I(p, 'r') < I(p, 'K') && I(p, 'K') < I(p, 'R')) || (I(p, 'R') < I(p, 'K') && I(p, 'K') < I(p, 'r' .map!toUpper.array.sort().uniq; writeln(starts.walkLength, "\n", starts.front); } I saw this answer for a similar question from Adam D. Ruppe: Quote: "...it is anything that Phobos considers "bidirectional" and "swappable" - an array it can reverse easily and swap individual elements, and it considers plain string to be non-swappable due to UTF-8 encoding. Due to its variable length element encoding, swapping two chars may require reshuffling the entire array, which would be far more expensive than the function allows. Thus, the easiest way to make this work is to use a type which Phobos considers to be swappable: a UTF-32 string, aka dchar[]." So, here's my attempt at something that might work for you: const pieces = "KQRrBbNN"; alias I = indexOf; auto starts = permutations(pieces.to!(dchar[])).filter!(p => I(p, 'B') % 2 != I(p, 'b') % 2 && // Bishop constraint. // King constraint. ((I(p, 'r') < I(p, 'K') && I(p, 'K') < I(p, 'R')) || (I(p, 'R') < I(p, 'K') && I(p, 'K') < I(p, 'r' .map!(to!string) .map!(toUpper).array.sort().uniq; writeln(starts.walkLength, "\n", starts.front); Note: the ".map!(to!string)" part was just to get round dealing with the fact that permutations returns an Index. It's may not be exactly what you want, but hopefully set you on the right track. Jordan
Re: Mixing libraries
On Thursday, 2 March 2017 at 01:02:39 UTC, Mike Parker wrote: On Wednesday, 1 March 2017 at 16:12:06 UTC, bauss wrote: There is a better binding. dsfml. You can find it here: http://dsfml.com/ DSFML technically is not a binding (even though it says such on the web site). It's a wrapper that D-ifies the SFML API. The SFML functions are not callable directly, as they are all declared privately. DerelictSFML is strictly a binding, with no attempt to wrap anything. A wrapper like DSFML could be implemented on top of DerelictSFML. So yes, it's better if what you really want is a wrapper. Ah yes, I think you explain the difference between wrapper/binding in one of the Derelict docs. I'm currently working through a ebook on Game Dev with SFML...the examples are all C++. I don't have any trouble translating it to the equivalent C bindings (so far anyway), but perhaps in the long run using dsfml will be easier (for example, I found using Iup4d easier than the straight C Iup bindings).
Re: code D'ish enough? - ignore previous post with same subject
On Tuesday, 28 February 2017 at 20:49:39 UTC, crimaniak wrote: On Sunday, 26 February 2017 at 21:50:38 UTC, Jordan Wilson wrote: .map!(a => a.to!double) If lambda just calls another function you can pass it directly: == .map!(to!double) Learn something new everyday, thanks :-)
Mixing libraries
Hello, Been trying to learn the Simple Fast Multimedia Library (SFML) using the Derelict bindings, and noticed some functionality is offered by both SFML and the std library (for example, sfClock and sfMutex). Is there a general design principle of, say, use the std library whenever possible and only SFML when I have too? Or should I try to be consistent and use SFML library whenever possible? Thanks, Jordan
Re: code D'ish enough? - ignore previous post with same subject
On Sunday, 26 February 2017 at 19:34:33 UTC, thorstein wrote: Hi, sorry for posting again, but I used a keyboard combination that accidently send my post before it was done. Coming more or less from Python I just started with D. Not a real programmer, just automating things and looking for a neat compiled language. Just to learn, I wrote a function to read CSV-like files (I know D has its own routine). Since I'm still a bit overwhelmed by the many complex language features, I'm curious what could I change to make my code as D'ish as possible? Thank you for any suggestion, Thorstein // Reads CSV-like files with only numeric values in each column // new_ndv replaces ndv, which is the original no-data-value double[][]* readNumMatCsv(char[] filePath, int numHeaderLines, char[] ndv, char[] new_ndv) { double[][]* p_numArray; double[][] numArray; char[] line; string noCont = "File content not usable. Quit here."; string noFile = "Could not read file. Quit here."; string nonNum = "Found a non-numeric value in data matrix. Quit here."; Regex!char re = regex(r"(\n$)"); if(exists(filePath)) { File f = File(filePath, "r"); if((line = f.readln().dup).length > 0) { while (!f.eof()) // 1st replace ndv with new_ndv, 2nd remove all \n, 3rd check id size of read line >0 { if((line = replaceAll(f.readln().dup.replace(ndv, new_ndv), re, "")).length > 0) // check if all elements of splitted line are numeric { foreach(i;split(line,",")) { if(isNumeric(i) == false) // otherwise return pointer to empty array { writeln(nonNum); return p_numArray; } } // convert characters to double if(split(line,",").length > 0) { numArray ~= to!(double[])(split(line,",")); } } } // pass reference to pointer p_numArray = &numArray; // first line empty -> return pointer to empty array } else { writeln(noCont); } // file could not be find } else { writeln(noFile); } return p_numArray; } I'm in a similar boat, as I continue to learn D, I find myself using UFCS, "auto", and operating on ranges alot more; I think that's considered idiomatic. For example, here is my rough attempt: auto readNumMatCsv2 (string filePath, string ndv, string new_ndv){ double[][] p_numArray; try { auto lines = File(filePath,"r").byLine; lines.popFront; // get read of header p_numArray = lines.map!(a => a.replace (ndv,new_ndv) .splitter (",") .map!(a => a.to!double) .array) .array; } catch (Exception e){ e.msg.writeln; // this replaces "Could not read file. Quit here." } return p_numArray; } It took me quite a while to get the whole usage of range stuff like "map" and "filter" etc., but I think it's worth the effort.
Re: D idom for removing array elements
On Sunday, 29 January 2017 at 23:42:40 UTC, Jordan Wilson wrote: On Sunday, 29 January 2017 at 21:41:57 UTC, albert-j wrote: On Saturday, 28 January 2017 at 11:54:58 UTC, cym13 wrote: [...] I am trying to wrap my head around lazy evaluation during filtering/mapping, but there's something I don't understand. I want to create an array, square some elements, remove some elements from original array and add the squared ones to the original array: [...] You need to do something like this: auto arrMap = arr.filter!(x => x > 5).map!(x => x^^2).array; It's because arrMap is lazy evaluated. Specifically: arr ~= arrMap.array; will cause arrMap to be evaluated again using whatever arr is. So instead of: auto arrMap = arr.filter!(x => x > 5).map!(x => x^^2); // mutate arr arr ~= arrMap.array; you would want: auto arrMap = arr.filter!(x => x > 5).map!(x => x^^2).array; // mutate arr arr ~= arrMap;
Re: D idom for removing array elements
On Sunday, 29 January 2017 at 21:41:57 UTC, albert-j wrote: On Saturday, 28 January 2017 at 11:54:58 UTC, cym13 wrote: [...] I am trying to wrap my head around lazy evaluation during filtering/mapping, but there's something I don't understand. I want to create an array, square some elements, remove some elements from original array and add the squared ones to the original array: [...] You need to do something like this: auto arrMap = arr.filter!(x => x > 5).map!(x => x^^2).array; It's because arrMap is lazy evaluated.
Re: D idom for removing array elements
On Thursday, 26 January 2017 at 08:22:09 UTC, albert-j wrote: What is the D idiom for removing array elements that are present in another array? Is this the right/fastest way? int[] a = [1, 2, 3, 4, 5, 6, 7, 4]; int[] b = [3, 4, 6]; auto c = a.remove!(x => b.canFind(x)); assert(c == [1, 2, 5, 7]); If you don't care about array a being mutated, then I think what you have is best (although I would suggest that if you don't care about a being mutated, just reassign the results back to a again). Otherwise, I think you need to allocate a new array, so the other answers using filter are good.
Re: Function template advice
On Wednesday, 18 January 2017 at 22:39:02 UTC, Ali Çehreli wrote: On 01/18/2017 02:02 PM, Jordan Wilson wrote: [...] Yes, can be better with something similar to the following: struct Foo { string bar; } string value(U : Foo)(U u) { return u.bar; } string value(U : string)(U u) { return u; } auto sameGroup(T,S) (T a, S b) { static assert (is(T == string) || is(T == Foo)); static assert (is(S == string) || is(S == Foo)); import std.algorithm; return equal (value(a), value(b)); } void main() { assert(sameGroup("a", "b") == false); assert(sameGroup("a", Foo("a")) == true); assert(sameGroup(Foo("x"), "b") == false); assert(sameGroup(Foo("z"), Foo("z")) == true); } Ali Nice, yes looks better thanks. Jordan
Function template advice
I have a simple comparison function: struct Foo { string bar; } auto sameGroup(T,S) (T a, S b) { static assert (is(T == string) || is(T == Foo)); static assert (is(S == string) || is(S == Foo)); string aStr; string bStr; static if (is(T == string)){ aStr = a; } else { aStr = a.bar; } static if (is(S == string)){ bStr = b; } else { bStr = b.bar; } return equal (aStr,bStr); } This works, but just wondered if there was an easier way? Is there a way to do "static if" in shorthand, like: auto aStr = (static if (is(T==string)) ? a : a.bar
Tuple fields/types
Hello, For tuples, does the fieldNames property have a 1-1 correspondence with the Types property? It appears that way in my testing: alias MyData = Tuple!(string,"a",int,"b"); foreach (i, type; MyData.Types){ writeln (MyData.fieldNames[i]," ",type.stringof); // a string // b int } But I can't figure out for sure from the documentation: alias fieldNames = staticMap!(extractName, fieldSpecs); alias Types = staticMap!(extractType, fieldSpecs); Thanks, Jordan
Re: reading file byLine
On Friday, 4 September 2015 at 00:18:15 UTC, Namal wrote: On Thursday, 3 September 2015 at 23:54:44 UTC, H. S. Teoh wrote: [...] Thx Theo, this and the lack of foolproof tutorials were the reason why I gave up on D 2 years ago and went instead to C++. But I am not giving up this time. That being said, when do I have to import std.array and std.string? Every time I use std.array? I can obviously use arrays and strings without those libs. My 2 cents, as someone who is newish to D, I'd also recommend the above approach. I found the whole ranges thing to be hard to get at first, but I do find myself using ranges + std.algorithm more and more (even though it's mostly just basic map and filter).
Re: reading file byLine
On Thursday, 3 September 2015 at 23:28:37 UTC, Namal wrote: On Thursday, 3 September 2015 at 23:25:52 UTC, Jordan Wilson wrote: And also: import std.algorithm Sorry, I should have taken the time to answer properly and fully. import std.file, std.stdio, std.string, std.conv, std.algorithm; void main(){ auto file = File("text.txt"); auto numbers = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array(); writeln(numbers); } Error: no property 'array' for type 'MapResult!(__lambda2, MapResult!(__lambda1, ByLine!(char, char)))' Still an error. import std.array
Re: reading file byLine
And also: import std.algorithm Sorry, I should have taken the time to answer properly and fully.
Re: reading file byLine
Actually, need an extra map I think: auto word = file.byLine() .map!(a => a.split) .map!(a => map!(a => to!int(a))(a)) .array();
Re: reading file byLine
On Thursday, 3 September 2015 at 22:48:01 UTC, Jordan Wilson wrote: On Thursday, 3 September 2015 at 22:21:57 UTC, Namal wrote: ep18.d(10): Error: no property 'split' for type 'char[]' /usr/include/dmd/phobos/std/algorithm.d(427): instantiated from here: MapResult!(__lambda1, ByLine!(char, char)) ep18.d(10):instantiated from here: map!(ByLine!(char, char)) and then a long list to the end of my code Error: undefined identifier a Hmm, seems I forgot to add std.string, now it works, but words seems not to be an array, at least I cannot access it like an array. words[0][0] leads to Error: no [] operator overload for type MapResult!(__lambda1, ByLine!(char, char)) So is is a map? How can I convert all the elements in it to integer and store it in a real array? I believe it's by using array: auto words = file.byLine() // you've all lines in range .map!(a => a.split).array(); Sorry, I didn't notice the "convert all the elements in it to integer" part. I think I saw reference to the to! before...that is one way to convert. auto words = file.byLine() // you've all lines in range .map!(a => a.split) .map!(a => to!int(a)).array();
Re: reading file byLine
On Thursday, 3 September 2015 at 22:21:57 UTC, Namal wrote: ep18.d(10): Error: no property 'split' for type 'char[]' /usr/include/dmd/phobos/std/algorithm.d(427): instantiated from here: MapResult!(__lambda1, ByLine!(char, char)) ep18.d(10):instantiated from here: map!(ByLine!(char, char)) and then a long list to the end of my code Error: undefined identifier a Hmm, seems I forgot to add std.string, now it works, but words seems not to be an array, at least I cannot access it like an array. words[0][0] leads to Error: no [] operator overload for type MapResult!(__lambda1, ByLine!(char, char)) So is is a map? How can I convert all the elements in it to integer and store it in a real array? I believe it's by using array: auto words = file.byLine() // you've all lines in range .map!(a => a.split).array();
Error Compiling with -debug swtich
Hello, Just wondering why compiling the following fails with the -debug switch, but appears to compile and execute fine without it: import std.stdio; import std.algorithm; import std.container; int main(string[] args) { Array!string letters = ["b","a","c"]; sort(letters[]); writeln (letters[]); // ["a","b","c"] return 0; } With the -debug switch, I get: src\phobos\std\range\package.d(7180): Error: 'std.range.SortedRange!(RangeT!(Array!string), "a < b").SortedRange.dbgVerifySorted' is not nothrow src\phobos\std\algorithm\sorting.d(982): Error: template instance std.range.assumeSorted!("a < b", RangeT!(Array!string)) error instantiating Without the switch, everything seems to work fine...(I'm using DMD 2.068.0) Thanks, Jordan