Re: Parsing with dxml
On Tuesday, 19 November 2019 at 04:43:31 UTC, Joel wrote: On Tuesday, 19 November 2019 at 02:45:29 UTC, Jonathan M Davis wrote: [...] Thanks for taking the time to reply. I have had another xml Bible version text in the past [1]. It had a different format. And Adam Ruppe helped me by writing code that worked (with just one tweak). I think I want another example that I can just paste into my program, using the same structs as the last xml version (see link). [1] https://forum.dlang.org/thread/j7ljs5$24r2$1...@digitalmars.com -class's (not structs)
Re: Parsing with dxml
On Tuesday, 19 November 2019 at 02:45:29 UTC, Jonathan M Davis wrote: On Sunday, November 17, 2019 11:44:43 PM MST Joel via Digitalmars-d-learn wrote: [...] You need to be checking the type of the entity before you call either name or text on it, because not all entities have a name, and not all entities have text - e.g. is an EntityType.elementStart, so it has a name (which is "field"), but it doesn't have text, whereas the 01001001 between the and tags has no name but does have text, because it's an EntityType.text. If you call name or text without verifying the type first, then you're almost certainly going to get an assertion failure at some point (assuming that you don't compile with -release anyway), since you're bound to end up with an entity that you don't expect at some point (either because you were wrong about where you were in the document, or because the document didn't match the layout that was expected). [...] Thanks for taking the time to reply. I have had another xml Bible version text in the past [1]. It had a different format. And Adam Ruppe helped me by writing code that worked (with just one tweak). I think I want another example that I can just paste into my program, using the same structs as the last xml version (see link). [1] https://forum.dlang.org/thread/j7ljs5$24r2$1...@digitalmars.com
Re: Getting all types defined in a module at compile time
On Tuesday, 19 November 2019 at 01:55:17 UTC, Paul Backus wrote: On Monday, 18 November 2019 at 21:48:00 UTC, Ben Jones wrote: template notmodule(alias T){ alias notmodule = __traits(isModule, T); } [...] I get errors: ``` (on the alias notmodule line) Error: trait isModule is either invalid or not supported in alias ``` The result of __traits(isModule, T) is a boolean value, so the line should be enum notmodule = __traits(isModule, T); Thanks! Is there a good resource on D metaprogramming somewhere? I'm kind of stumbling my way through things and would love to see some best practices laid out somewhere.
Re: Parsing with dxml
On Sunday, November 17, 2019 11:44:43 PM MST Joel via Digitalmars-d-learn wrote: > I can only parse one row successfully. I tried increasing the > popFronts, till it said I'd gone off the end. > > Running ./app > core.exception.AssertError@../../../../.dub/packages/dxml-0.4.1/dxml/sourc > e/dxml/parser.d(1457): text cannot be called with elementEnd > > ??:? _d_assert_msg [0x104b3981a] > ../../JMiscLib/source/jmisc/base.d:161 pure @property @safe > immutable(char)[] dxml.parser.EntityRange!(dxml.parser.Config(1, > 1, 1, 1), immutable(char)[]).EntityRange.Entity.text() > [0x104b2297b] > source/app.d:26 _Dmain [0x104aeb46e] > Program exited with code 1 > > ``` > > > http://www.w3.org/2001/XMLSchema-instance";> > > 01001001 > 1 > 1 > 1 > In the beginning God created the heavens and the > earth. > > > > 01001002 > 1 > 1 > 2 > And the earth was waste and void; and darkness > was upon the face of the deep: and the Spirit of God moved upon > the face of the waters. > > > ``` > > ```d > void main() { > import std.stdio; > import std.file : readText; > import dxml.parser; > import std.conv : to; > > struct Verse { > string id; > int b, c, v; > string t; > } > > auto range = parseXML!simpleXML(readText("xmltest.xml")); > > // simpleXML skips comments > > void pops(int c) { > foreach(_; 0 .. c) > range.popFront(); > } > pops(3); > > Verse[] vers; > foreach(_; 0 .. 2) { > Verse ver; > ver.id = range.front.text; > pops(3); > ver.b = range.front.text.to!int; > pops(3); > ver.c = range.front.text.to!int; > pops(3); > ver.v = range.front.text.to!int; > pops(3); > ver.t = range.front.text; > > with(ver) > vers ~= Verse(id,b,c,v,t); > > pops(2); > } > foreach(verse; vers) with(verse) > writeln(id, " Book: ", b, " ", c, ":", v, " -> ", t); > } > ``` You need to be checking the type of the entity before you call either name or text on it, because not all entities have a name, and not all entities have text - e.g. is an EntityType.elementStart, so it has a name (which is "field"), but it doesn't have text, whereas the 01001001 between the and tags has no name but does have text, because it's an EntityType.text. If you call name or text without verifying the type first, then you're almost certainly going to get an assertion failure at some point (assuming that you don't compile with -release anyway), since you're bound to end up with an entity that you don't expect at some point (either because you were wrong about where you were in the document, or because the document didn't match the layout that was expected). Per the assertion's message, you managed to call text on an EntityType.elementEnd, and per the stack trace, text was called on this line ver.id = range.front.text; If I add if(range.front.type == EntityType.elementEnd) { writeln(range.front.name); writeln(range.front.pos); } right above that, I get row TextPos(11, 4) indicating that the end tag was and that it was on line 11, 4 code units in (and since this is ASCII, that would be 4 characters). So, you managed to parse all of the *** lines but didn't correctly deal with the end of that section. If I add writeln(range.front); right before pops(2); then I get: Entity(text, TextPos(10, 25), , Text!(ByCodeUnitImpl)(In the beginning God created the heavens and the earth., TextPos(10, 25))) So, prior to popping twice, it's on the text between and , which looks like it's what you intended. If you look at the XML after that, it should be clear why you're in the wrong place afterwards. Since at that point, range.front is on the EntityType.text between and , popping once makes it so that range.front is . And popping a second time makes range.front , which is where the range is when it the tries to call text at the top of the loop. Presumably, you want it to be on the EntityType.text in 01001002 To get there from , you'd have to pop once to get to , a second time to get to , and a third time to get to 01001002. So, if you had pops(5); instead of pops(2); the range would be at the correct place at the top of the loop - though it would then be the wrong number of times to pop the second time around. With the text as provided, it would throw an XMLParsingException when it reached the end of the loop the second time, because the XML document doesn't have the matching tag, and with that fixed, you end up with an assertion failure, because popFront was called on an empty range (since there aren't 7 elements left in the range at that point): core.exception.AssertError@../../.dub/packages/dxml-0.4.0/dxml/source/dxml /parser.d(1746): It's illegal to call popFront(
Re: Getting all types defined in a module at compile time
On Monday, 18 November 2019 at 21:48:00 UTC, Ben Jones wrote: template notmodule(alias T){ alias notmodule = __traits(isModule, T); } [...] I get errors: ``` (on the alias notmodule line) Error: trait isModule is either invalid or not supported in alias ``` The result of __traits(isModule, T) is a boolean value, so the line should be enum notmodule = __traits(isModule, T);
Re: Deserializing JSON as an abstract type
On Tuesday, 19 November 2019 at 00:40:16 UTC, Chris wrote: So I'm trying to make a D wrapper for Telegram's JSON API using libtdjson. All results coming from the JSON API take the following structure: { "@type": "className", "foo": "bar", "baz" { "@type": "otherClass" } } where every object, including nested ones, has a "@type" field which will correspond to a D class. There will be over 770 possible types. So what I'm trying to figure out is how to deserialize the JSON so that it automatically gets parsed into the correct type. I'm looking at asdf right now, but it doesn't seem like it has anything like that built in. Any ideas? Can you have a look at this : https://github.com/huntlabs/hunt/blob/master/examples/UnitTest/source/test/JsonSerializerTest.d The JsonSerializer can serialize and deserialize a complex class.
Deserializing JSON as an abstract type
So I'm trying to make a D wrapper for Telegram's JSON API using libtdjson. All results coming from the JSON API take the following structure: { "@type": "className", "foo": "bar", "baz" { "@type": "otherClass" } } where every object, including nested ones, has a "@type" field which will correspond to a D class. There will be over 770 possible types. So what I'm trying to figure out is how to deserialize the JSON so that it automatically gets parsed into the correct type. I'm looking at asdf right now, but it doesn't seem like it has anything like that built in. Any ideas?
DUB project type support for Emacs Projectile
Have anybody written support for DUB project types in Emacs' projectile? See: https://www.projectile.mx/en/latest/projects/#adding-custom-project-types
Building DMD via Digger with maximum optimizations
How do I build dmd/druntime/phobos via Digger with maximum optimizations during the build of the compiler itself like what you get via make -f posix.mak HOST_DMD=ldmd2 ENABLE_RELEASE=1 I'm currenly using dub run digger --build=release -- build
Re: What is the replacement for deprecated array removal
On Monday, 18 November 2019 at 21:25:12 UTC, kerdemdemir wrote: It is a bit weird that such a general case like removing list of elements does not work. And I really do not know the real use of [0,1,2,3].remove(1,2,3). I mean in unit test it looks cool but in real life you will have dynamically calculated indexes. Erdem It seems like a defect in phobos to me as well. Fortunately phobos is written in D so you can just copy&paste this into your code: https://github.com/dlang/phobos/blob/master/std/algorithm/mutation.d#L2160 however, it still doesn't return the same thing as x.remove(1,2,3). ... maybe it'd be simpler to drop down to C-style D? // no checks for out-of-bounds or unsorted offsets void myRemove(ref int[] array, int[] offsets) { int from, to, offset; while (from < array.length) { if (offset < offsets.length && from == offsets[offset]) { ++offset; ++from; } else if (from == to) { ++to; ++from; } else { array[to++] = array[from++]; } } array.length = to; } unittest { int[] x = [1, 2, 3]; int[] y = x.dup, z = x.dup, q = x.dup; myRemove(x, [0]); myRemove(y, []); myRemove(z, [2]); myRemove(q, [1, 2]); assert(x == [2, 3]); assert(y == [1, 2, 3]); assert(z == [1, 2]); assert(q == [1]); } Perhaps it's nice to have the option?
Re: Strange double to uint conversion
On 11/18/19 4:54 PM, Steven Schveighoffer wrote: What you may want to do is use std.math.ceil. Sorry, what you want is std.math.round. -Steve
Re: What's the difference between sourcePaths and importPaths in DUB?
On Monday, 18 November 2019 at 21:44:06 UTC, WhatMeWorry wrote: The documentation doesn't go into much detail: sourcePaths "" ["" [...]] Allows to customize the path where to look for source files (any folder "source" or "src" is automatically used as a source path if no sourcePaths setting is specified) - note that you usually also need to define "importPaths" as "sourcePaths" don't influence those sourcePaths are used when the package is compiled, importPaths are used for looking up imports so other packages which depends on the package knows where to look for them.
Re: Strange double to uint conversion
On 11/18/19 4:08 PM, Luiz Silveira wrote: Hello, everyone! I'm a new D fan, still learning the language and this is my first post. I came up with a strange behavior, using D 2.089 for windows. Considering the program "error.d": import std.stdio; import std.conv; void main() { uint c(double v) { return (37.05*100.0).to!uint; } double f; uint c2(double v) { return (37.05*f).to!uint; } f=100.0; writeln("All should be 3705, right? -- ", 37.05*100, "; ", 37.05*100.0, "; ", (37.05*100).to!uint, "; ",c(37.05),"; ",c2(37.05)); } I expect all values to be 3705, yet running it with '/c/D/dmd-2.089.0/windows/bin/dmd.exe -run error.d' gives me the output: All should be 3705, right? -- 3705; 3705; 3705; 3705; 3704 I also played with several compilation options, all yelding the same results: dmd -boundscheck=on -m64 -lowmem -of="error" "error".d && ./error dmd -boundscheck=off -m64 -lowmem -of="error" "error".d && ./error dmd -boundscheck=on -m32 -lowmem -of="error" "error".d && ./error dmd -release -O -mcpu=native -boundscheck=on -m64 -lowmem -of="error" "error".d && ./error dmd -release -O -mcpu=native -boundscheck=on -m64 -of="error" "error".d && ./error dmd -of="error" "error".d && ./error What am I doing wrong? You are expecting floating point to behave as if it is stored as a decimal number. It's not. An interesting thing is that 5/100 (or 1/20) is not accurately representable in floating point. So you get an approximation in some cases (actually in all cases), but happens to print the right thing. What you may want to do is use std.math.ceil. -Steve
Getting all types defined in a module at compile time
I'm trying to get a list of all the types defined in a module at compile time (enums, structs, classes). I attempted to use the isAggregateType trait, but it choked when it was passed modules that had been imported (object, and the others explicitly imported). My next attempt was to try to filter out the modules, then look at everything left over with things like isAggregateType, etc. However, I'm getting errors when trying to filter on isModule. Am I missing out on a simpler/more direct approach? Is there a workaround to this alias error? ``` module thismodule; import std.meta; import std.traits; struct S{} enum E {asdf}; class C{} template symbols(alias mod){ alias getSymbol(alias T) = __traits(getMember, mod, T); alias symbols = staticMap!(getSymbol, __traits(allMembers, mod)); } template notmodule(alias T){ alias notmodule = __traits(isModule, T); } void main(){ static foreach(s; symbols!thismodule){ pragma(msg, fullyQualifiedName!s); } alias notmods = Filter!(templateNot!notmodule, symbols!thismodule); } ``` I get errors: ``` (on the alias notmodule line) Error: trait isModule is either invalid or not supported in alias ```
What's the difference between sourcePaths and importPaths in DUB?
The documentation doesn't go into much detail: sourcePaths "" ["" [...]] Allows to customize the path where to look for source files (any folder "source" or "src" is automatically used as a source path if no sourcePaths setting is specified) - note that you usually also need to define "importPaths" as "sourcePaths" don't influence those
Re: What is the replacement for deprecated array removal
On Monday, 18 November 2019 at 21:14:53 UTC, Steven Schveighoffer wrote: On 11/18/19 3:53 PM, kerdemdemir wrote: Is there any way to remove list of elements efficiently with a dynamical array? It seems kind of silly that it's not allowed, but maybe it will be possible after the deprecation is removed. But you could do something like this: list = list.remove!(a => removeList.canFind(a)); This is going to suck. Because it's O(n^2). Should be O(n + m) way to do it (assuming you have a sorted index list). Or is there anyway converting a dynamical array into a form which is like a AliasSeq? An AliasSeq is a compile-time construct, and cannot be created from a runtime array. -Steve Thanks for awesome answers man , Yes that sucks real hard because unlike that dummy example in my real case == compression will be too expensive I can't simply use canFind on every index. I guess I need to recreate a new dynamical array each time which is also horrible. It is a bit weird that such a general case like removing list of elements does not work. And I really do not know the real use of [0,1,2,3].remove(1,2,3). I mean in unit test it looks cool but in real life you will have dynamically calculated indexes. Erdem
Re: Strange double to uint conversion
On Monday, 18 November 2019 at 21:14:37 UTC, mipri wrote: double f; If this is changed to `real f;`, you get the desired result. real is also the type used for the comparison code: https://dlang.org/spec/float.html#fp_const_folding Yes, it worked as expected. Thank you, Luiz.
Re: What is the replacement for deprecated array removal
On 11/18/19 3:53 PM, kerdemdemir wrote: Is there any way to remove list of elements efficiently with a dynamical array? It seems kind of silly that it's not allowed, but maybe it will be possible after the deprecation is removed. But you could do something like this: list = list.remove!(a => removeList.canFind(a)); This is going to suck. Because it's O(n^2). Should be O(n + m) way to do it (assuming you have a sorted index list). Or is there anyway converting a dynamical array into a form which is like a AliasSeq? An AliasSeq is a compile-time construct, and cannot be created from a runtime array. -Steve
Re: Strange double to uint conversion
On Monday, 18 November 2019 at 21:08:39 UTC, Luiz Silveira wrote: double f; If this is changed to `real f;`, you get the desired result. real is also the type used for the comparison code: https://dlang.org/spec/float.html#fp_const_folding
Strange double to uint conversion
Hello, everyone! I'm a new D fan, still learning the language and this is my first post. I came up with a strange behavior, using D 2.089 for windows. Considering the program "error.d": import std.stdio; import std.conv; void main() { uint c(double v) { return (37.05*100.0).to!uint; } double f; uint c2(double v) { return (37.05*f).to!uint; } f=100.0; writeln("All should be 3705, right? -- ", 37.05*100, "; ", 37.05*100.0, "; ", (37.05*100).to!uint, "; ",c(37.05),"; ",c2(37.05)); } I expect all values to be 3705, yet running it with '/c/D/dmd-2.089.0/windows/bin/dmd.exe -run error.d' gives me the output: All should be 3705, right? -- 3705; 3705; 3705; 3705; 3704 I also played with several compilation options, all yelding the same results: dmd -boundscheck=on -m64 -lowmem -of="error" "error".d && ./error dmd -boundscheck=off -m64 -lowmem -of="error" "error".d && ./error dmd -boundscheck=on -m32 -lowmem -of="error" "error".d && ./error dmd -release -O -mcpu=native -boundscheck=on -m64 -lowmem -of="error" "error".d && ./error dmd -release -O -mcpu=native -boundscheck=on -m64 -of="error" "error".d && ./error dmd -of="error" "error".d && ./error What am I doing wrong?
Re: What is the replacement for deprecated array removal
On Monday, 18 November 2019 at 20:48:40 UTC, kerdemdemir wrote: On Monday, 18 November 2019 at 20:37:50 UTC, Steven Schveighoffer wrote: If I follow the code correctly, it's treating your array as a tuple of pos/len to remove. So it looks like your code is equivalent to remove(tuple(0, 2)); Which is probably not what you want. This probably explains why it's being deprecated, it's too confusing to the compiler. And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154 -Steve Sorry to be horrible at explaining but remove(tuple(0, 2)); is not what I want. I have an array which goes from 0 to 5. And I want to remove odd numbers. remove(tuple(0, 2)); defines a starting index and a ending index but I need to delete not consecutive elements. In the case of odd number from 0 to 5 that will be 1, 3 and 5 . It is so weird when you type it is allowed like remove(1, 3, 5) but unexpectedly remove([1,3,5]) does not work the same way. I think if I can convert [1,3,5] to a AliasSeq that could be ok also. Erdem I read your message again now and I see that you weren't suggesting remove(tuple(0, 2)) but you were pointing out it is not what I want as well. Is there any way to remove list of elements efficiently with a dynamical array? Or is there anyway converting a dynamical array into a form which is like a AliasSeq? Erdem
Re: What is the replacement for deprecated array removal
On Monday, 18 November 2019 at 20:37:50 UTC, Steven Schveighoffer wrote: If I follow the code correctly, it's treating your array as a tuple of pos/len to remove. So it looks like your code is equivalent to remove(tuple(0, 2)); Which is probably not what you want. This probably explains why it's being deprecated, it's too confusing to the compiler. And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154 -Steve Sorry to be horrible at explaining but remove(tuple(0, 2)); is not what I want. I have an array which goes from 0 to 5. And I want to remove odd numbers. remove(tuple(0, 2)); defines a starting index and a ending index but I need to delete not consecutive elements. In the case of odd number from 0 to 5 that will be 1, 3 and 5 . It is so weird when you type it is allowed like remove(1, 3, 5) but unexpectedly remove([1,3,5]) does not work the same way. I think if I can convert [1,3,5] to a AliasSeq that could be ok also. Erdem
Re: What is the replacement for deprecated array removal
On 11/18/19 3:01 PM, kerdemdemir wrote: int[] removeList; for ( int i = 0; i < tempMap[0].length; i++ ) { if ( i%2 == 0 ) removeList ~=i; } writeln(removeList); (prints 0,2,4) tempMap[1].remove(0,2,4); tempMap[2].remove(removeList); tempMap[3].remove(tuple(0,1),tuple(2,3),tuple(4,5) ); Even weirder(at least for me) int[] removeList is [0,2,4] And .remove returns different results for .remove(0,2,4); and ..remove(removeList) Is there anyway to convert int[] to a sequence like 0,2,4 Erdem If I follow the code correctly, it's treating your array as a tuple of pos/len to remove. So it looks like your code is equivalent to remove(tuple(0, 2)); Which is probably not what you want. This probably explains why it's being deprecated, it's too confusing to the compiler. And looking at git blame goes back to this PR: https://github.com/dlang/phobos/pull/6154 -Steve
Re: What is the replacement for deprecated array removal
int[] removeList; for ( int i = 0; i < tempMap[0].length; i++ ) { if ( i%2 == 0 ) removeList ~=i; } writeln(removeList); (prints 0,2,4) tempMap[1].remove(0,2,4); tempMap[2].remove(removeList); tempMap[3].remove(tuple(0,1),tuple(2,3),tuple(4,5) ); Even weirder(at least for me) int[] removeList is [0,2,4] And .remove returns different results for .remove(0,2,4); and .remove(removeList) Is there anyway to convert int[] to a sequence like 0,2,4 Erdem
Re: Troubleshooting DUB invocations
On Wednesday, 13 November 2019 at 18:10:15 UTC, Dukc wrote: On Wednesday, 13 November 2019 at 15:41:01 UTC, Sebastiaan Koppe wrote: It has been on the back of my mind since 1.18-beta came out. I am going to reserve a little time tomorrow to work on it. Regarding that, perhaps I can save you a bit trouble if you also try to get 1.19 working: if you get compile errors related to SortedRange, the fix is https://github.com/dlang/phobos/pull/7266. I have had some time today to look into this. About the --no-as-needed: TL;DR: add `--build-mode=allAtOnce` to the dub command. Kinke made some changes in dub to facilitate separate linking for ldc. I am not aware of all the details but the major benefit is that it allows cross compilation with dub and ldc. Because of the separate linking the --no-as-needed turned up. As far as I can see it is only needed when compiling for linux. Which brings up the question, why linux? Aren't we compiling for wasm? Well yes. But that is just the way things worked up until now, ldc and dub just pick the host machine. Luckily there is the new dub `--arch` argument that can take a llvm triple, in our case wasm32-unknown-unknown-wasm. This causes dub not to add the `--no-as-needed`. Except, that it also passes the triple upwards the dependency tree. Now all the dependencies of spasm get compiled targeting wasm. This is a good thing, except that the optional package which spasm depends on fails to compile with it. There is a newer version that fixes the configuration, but that one fails because of the `from.std` import idiom (it imports the std package from phobos which doesn't recognise wasm and fails with "Unknown OS"). In the end it is all caused by phobos and druntime not knowing anything about wasm. Which I am currently working on behind the scenes to fix. In the meantime I am going to make a PR for the optional package to avoid the `from.std` idiom. Although I might end up playing whack-a-mole here, as there might be more dependencies that need a fix now. Another workaround that you can use right now is by adding the `--build-mode=allAtOnce` argument to dub. It effectively gets you the old behaviour. It is what I am using in my CI to get it to go green again.
Re: dmd memory usage
On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: I'm fighting some out of memory problems using DMD and some super-template heavy code. I have ideas on how to improve the situation, but it involves redesigning a large portion of the design. I want to do it incrementally, but I need to see things improving. Is there a straightforward way to figure out how much memory the compiler uses during compilation? I though maybe /usr/bin/time, but I feel like I don't trust the output to be the true max resident size to be what I'm looking for (or that it's 100% accurate). Is there a sure-fire way to have DMD print it's footprint? -Steve Massif is good for this. ms_print will give you a graphical summary, and the data is human and machine readable. The only setback being that massif can make the execution slower however I can't give exact numbers but it can be terrible.
Re: ints.choice vs. chars.choice
On Mon, Nov 18, 2019 at 7:25 PM Steven Schveighoffer via Digitalmars-d-learn wrote: > > > You could also use cast(dchar[]), and avoid the cast back to char. > > -Steve or use byCodeUnit writeln(['a', 'b', 'c'].byCodeUnit.choice);
Re: Use my private phobos version in dub project
On 11/18/19 12:46 PM, Tobias Pankrath wrote: Hi, I wanted to hack a bit on phobos and wondered what the best way is to use my own version in a project managed by dub. I have used the dlang/tools/setup.sh and got ../d/dmd, .../d/phobos/ ../d/druntime etc. Now I want to hack on phobos and use that version in a project of mine to test the changes. What's the best way to do this? I've searched the wiki, but didn't find anything useful. Thanks! Dub uses the standard library provided by your compiler, it doesn't download it from the repository. You need to edit your dmd.conf or dmd.ini file (depending on what platform you are on) to point at your version of the library. I recommend making a separate directory with the conf you want, and copying or syslinking the compiler there. -Steve
What is the replacement for deprecated array removal
I know my example can be shortened but please excuse me that I am pasting directly import std.stdio; import std.math; import std.range; import std.algorithm; import std.typecons; int[][4] tempMap; void main() { int[] temp = [ 1, 2, 3 , 4 ,5 ]; tempMap[0] = temp.dup; tempMap[1] = temp.dup; tempMap[2] = temp.dup; tempMap[3] = temp.dup; int[] removeList; for ( int i = 0; i < tempMap.length; i++ ) { if ( i%2) removeList ~=i; } tempMap[1].remove(removeList); writeln(tempMap); } Results with that warning: onlineapp.d(24): Deprecation: function std.algorithm.mutation.remove!(cast(SwapStrategy)2, int[], int[]).remove is deprecated How can I remove a list of indexes with remove ? Erdem
Re: ints.choice vs. chars.choice
On 11/18/19 12:32 PM, mipri wrote: Howdy, The following program fails to compile if the second line is uncommented: import std; void main() { writeln([1, 2, 3].choice); //writeln(['a', 'b', 'c'].choice); } Error: template std.random.choice cannot deduce function from argument types !()(char[], MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u)), candidates are: /usr/include/dmd/phobos/std/random.d(2559): std.random.choice(Range, RandomGen = Random)(auto ref Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen) /usr/include/dmd/phobos/std/random.d(2569): std.random.choice(Range)(auto ref Range range) What is going on here? I get it that choice() isn't simply an algorithm over T[], that there are some additional constraints, but surely a char[] is just as random acc... Nope, phobos treats a narrow character array (such as char[] or wchar[]) as a bidirectional range of dchar. It's called autodecoding, and it's continually causing problems for about 10 years now. Oh. It's because of emojicode. unicode. I hope that was a joke ;) This works: import std; void main() { writeln([1, 2, 3].choice); writeln(cast(char)(cast(uint8_t[])['a', 'b', 'c']).choice); You could also use cast(dchar[]), and avoid the cast back to char. -Steve
Use my private phobos version in dub project
Hi, I wanted to hack a bit on phobos and wondered what the best way is to use my own version in a project managed by dub. I have used the dlang/tools/setup.sh and got ../d/dmd, ../d/phobos/ ../d/druntime etc. Now I want to hack on phobos and use that version in a project of mine to test the changes. What's the best way to do this? I've searched the wiki, but didn't find anything useful. Thanks!
Re: Casting from int to long
On 11/18/19 7:16 AM, Yui Hosaka wrote: gives the output 950, while it should be 100. Looks like a bug. Confirmed with dmd 2.088.0 compiling with -O -m32 on Ubuntu. Ali
ints.choice vs. chars.choice
Howdy, The following program fails to compile if the second line is uncommented: import std; void main() { writeln([1, 2, 3].choice); //writeln(['a', 'b', 'c'].choice); } Error: template std.random.choice cannot deduce function from argument types !()(char[], MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u)), candidates are: /usr/include/dmd/phobos/std/random.d(2559): std.random.choice(Range, RandomGen = Random)(auto ref Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen) /usr/include/dmd/phobos/std/random.d(2569): std.random.choice(Range)(auto ref Range range) What is going on here? I get it that choice() isn't simply an algorithm over T[], that there are some additional constraints, but surely a char[] is just as random acc... ... Oh. It's because of emojicode. This works: import std; void main() { writeln([1, 2, 3].choice); writeln(cast(char)(cast(uint8_t[])['a', 'b', 'c']).choice); } and this outputs false: writeln(isRandomAccessRange!(char[])); I no longer have any questions but I wish the dlang.org docs were much more generous with examples.
Re: dmd memory usage
On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: I'm fighting some out of memory problems using DMD and some super-template heavy code. I have ideas on how to improve the situation, but it involves redesigning a large portion of the design. I want to do it incrementally, but I need to see things improving. Is there a straightforward way to figure out how much memory the compiler uses during compilation? I though maybe /usr/bin/time, but I feel like I don't trust the output to be the true max resident size to be what I'm looking for (or that it's 100% accurate). Is there a sure-fire way to have DMD print it's footprint? -Steve You can wrap the whole thing in a shell script that takes PID of the compiler, and uses psrecord [1] Python tool to give you CPU and memory chart. [1] https://pypi.org/project/psrecord/
Re: dmd memory usage
On 11/18/19 11:15 AM, Steven Schveighoffer wrote: On 11/18/19 10:36 AM, Jacob Carlborg wrote: On Monday, 18 November 2019 at 15:31:02 UTC, Steven Schveighoffer wrote: I don't think this will work for me, as this isn't CTFE, and I'm assuming the instantiated templates won't be collected because they stay referenced for the whole program. You could also combine that flag with the GC profiling flags. That's a good point. I tried the profiling flags, but realized really quickly that it doesn't use the GC. But if you told it to use the GC, then that info becomes relevant. I also noticed that dub suppresses the output of the profiler somehow (I had to run it with -v, and then run the compile line by hand to get it to do the profiling). Yeah, as I expected it still gets killed by the OOM killer. But still, good to know that switch exists. -Steve
Re: dmd memory usage
On 11/18/19 10:36 AM, Jacob Carlborg wrote: On Monday, 18 November 2019 at 15:31:02 UTC, Steven Schveighoffer wrote: I don't think this will work for me, as this isn't CTFE, and I'm assuming the instantiated templates won't be collected because they stay referenced for the whole program. You could also combine that flag with the GC profiling flags. That's a good point. I tried the profiling flags, but realized really quickly that it doesn't use the GC. But if you told it to use the GC, then that info becomes relevant. I also noticed that dub suppresses the output of the profiler somehow (I had to run it with -v, and then run the compile line by hand to get it to do the profiling). -Steve
Re: dmd memory usage
On Monday, 18 November 2019 at 15:31:02 UTC, Steven Schveighoffer wrote: I don't think this will work for me, as this isn't CTFE, and I'm assuming the instantiated templates won't be collected because they stay referenced for the whole program. You could also combine that flag with the GC profiling flags. — /Jacob Carlborg
Re: dmd memory usage
On 11/18/19 3:16 AM, Jacob Carlborg wrote: On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: I'm fighting some out of memory problems using DMD and some super-template heavy code. Try to enable the GC using the `-lowmem` flag [1]. [1] https://dlang.org/changelog/2.086.0.html#lowmem I don't think this will work for me, as this isn't CTFE, and I'm assuming the instantiated templates won't be collected because they stay referenced for the whole program. -Steve
Re: dmd memory usage
On 11/17/19 7:48 PM, ikod wrote: On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: I'm fighting some out of memory problems using DMD and some super-template heavy code. I have ideas on how to improve the situation, but it involves redesigning a large portion of the design. I want to do it incrementally, but I need to see things improving. Is there a straightforward way to figure out how much memory the compiler uses during compilation? I though maybe /usr/bin/time, but I feel like I don't trust the output to be the true max resident size to be what I'm looking for (or that it's 100% accurate). Is there a sure-fire way to have DMD print it's footprint? Hello, You can look at http://man7.org/linux/man-pages/man2/getrusage.2.html But, probably /usr/bin/time already use it. Yeah, that looks like what /usr/bin/time is doing. -Steve
Re: dmd memory usage
On 11/17/19 7:33 PM, Adam D. Ruppe wrote: On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: Is there a straightforward way to figure out how much memory the compiler uses during compilation? So this isn't a great solution but what I have done in the past is just have a little script running ps aux | grep dmd sleep 1 # or whatever time you want in a loop running in the background to gather some data as it goes. If combined with dmd -v you can interpolate the -v and ps output to get an idea of what the memory use is at a certain point of what the compiler is working on. again i know it isn't great but it is easy to play with and better than nothing Yeah, I started trying out valgrind, which seems to give a decent report. It slows down the compiler a bit, but that's ok. In any case, I realized that I need to write some more targeted tests, because the template I want to replace is used all over the place, so I would need to change them all in order to reduce memory usage. -Steve
Casting from int to long
On DMD32 D Compiler v2.089.0-dirty, Windows, the code import std.stdio; int f(int x) { return 1; } void main() { enum N = 100; auto a = new int[N]; a[] = 1; long sum; foreach_reverse (i; 0 .. N) { const r = i % 5; sum += cast(long)(a[i]) * f(r); } writeln(sum); } gives the output 950, while it should be 100. This happens only with -O and without -m64 option. I have encountered some kind of "32-bit / 64-bit issues" several times (https://issues.dlang.org/show_bug.cgi?id=20162, https://issues.dlang.org/show_bug.cgi?id=20128).
Re: Segfault when writing to module-scope dynamic array
On Monday, 18 November 2019 at 13:28:26 UTC, Adam D. Ruppe wrote: But it is rare and if you aren't specifically looking for it knowing the details, it isn't right. And since the syntax looks so normal it trips up a LOT of people. I think the compiler should probably start to error on it, and if you know what you're doing, maybe mark it special somehow. idk. Well, my fingers are singed. I'll know not to do that again, for what it's worth :)
Re: Segfault when writing to module-scope dynamic array
On Monday, 18 November 2019 at 13:22:20 UTC, rombankzero wrote: Yeah, that appears to be what's happening. For the record, I tried it on both Linux and Windows, and only got a segfault on Linux. Yeah, that's consistent with other strings too. (The D type system calls both immutable, but the OS is looser on Windows. at least 32 bit.) Are there cases where this behavior is useful? Yeah, it is cool for sentinel objects and default settings. Usually best when coupled with immutable to prevent more confusion but mutable versions sometimes make sense too. But it is rare and if you aren't specifically looking for it knowing the details, it isn't right. And since the syntax looks so normal it trips up a LOT of people. I think the compiler should probably start to error on it, and if you know what you're doing, maybe mark it special somehow. idk.
Re: Segfault when writing to module-scope dynamic array
On Monday, 18 November 2019 at 12:42:26 UTC, Adam D. Ruppe wrote: My guess is the compiler is seeing a static string and incorrectly putting it in the read-only segment with the other strings, and then writing to it thus triggers that segfault. Yeah, that appears to be what's happening. For the record, I tried it on both Linux and Windows, and only got a segfault on Linux. And the fact that the ubyte[] case works only added to the confusion. On Monday, 18 November 2019 at 12:42:26 UTC, Adam D. Ruppe wrote: but yeah this is NOT what it does. It runs new at *compile time* which means that `array` variable is pointing to static memory, it is not heap allocated at all. Are there cases where this behavior is useful? Because it seems pretty surprising to me. Like, when I see the "new" keyword, I immediately think "heap allocation", not anything being put into the data segment.
Re: Segfault when writing to module-scope dynamic array
On Monday, 18 November 2019 at 12:31:10 UTC, rombankzero wrote: char[] array = new char[5]; It is almost always wrong to new things at module, class, or struct scope, since this create it in the static data segment. My guess is the compiler is seeing a static string and incorrectly putting it in the read-only segment with the other strings, and then writing to it thus triggers that segfault. just a guess, and if correct, this is a dmd bug. But I'd still recommend doing the `new` inside a function/module constructor anyway. That takes the static aspect out entirely and prevents some surprising bugs (right now the new is run at CTFE, not a huge deal here but with like classes it surprises a lot of people as the default pointer is shared between instances!) I assumed it would heap-allocate a mutable dynamic array before main runs but yeah this is NOT what it does. It runs new at *compile time* which means that `array` variable is pointing to static memory, it is not heap allocated at all.
Segfault when writing to module-scope dynamic array
Hi! Can anybody explain why this snippet segfaults when I try to run it: char[] array = new char[5]; void main() { array[0] = 'a'; } It works fine if I move the array into main, or (strangely) if I change its type to ubyte[] instead of char[], or if I merely read the array without modifying it. I assumed it would heap-allocate a mutable dynamic array before main runs, but maybe I've misunderstood what `new` expressions do at module scope? Or is this some special case for char arrays (strings)? I really don't know what to make of it.
Re: dmd memory usage
On Monday, 18 November 2019 at 00:20:12 UTC, Steven Schveighoffer wrote: I'm fighting some out of memory problems using DMD and some super-template heavy code. Try to enable the GC using the `-lowmem` flag [1]. [1] https://dlang.org/changelog/2.086.0.html#lowmem — /Jacob Carlborg
Re: Parsing with dxml
On Monday, 18 November 2019 at 06:44:43 UTC, Joel wrote: with(ver) vers ~= Verse(id,b,c,v,t); Or, vers ~= ver;