Re: Wrapper around a recursive data type
On 09.07.2024 06:54, Steven Schveighoffer wrote: On Monday, 8 July 2024 at 08:56:51 UTC, drug007 wrote: How can I "break" this recursion or some other work around to fix it? A few ideas: 1. If it's immediately recursive (that is, contains a pointer to itself), just use the type itself somehow. You may not be able to do this with recursive templates. 2. If the data itself is static, and not actually containing different things, defer the construction of the Meta members until needed. In other words, make them structs with a member which accesses the meta when requested. 3. In a project I have which constructs a parallel type on existing types, I use `opDispatch` to defer instantiation of the members until later. This may or may not work for you depending on the use case (you can't introspect `opDispatch`). -Steve Decided to use untyped array (like void[]) and then a decorator to make it typed one. It seems to be working, testing in progress.
Wrapper around a recursive data type
I need to generate some meta info of my data types. I do it this [way](https://gist.github.com/drug007/b0a00dada6c6ecbf46b4f6988401d4e2): ```D import std.range, std.format, std.stdio, std.traits; struct NestedType { string s; double d; } struct Node { string value; int i; NestedType nt; // Node[] children; // It makes Node to be a recursive data types } template Meta(A) { static if (isRandomAccessRange!A) alias Meta = RaRMeta!A; else static if (isSomeString!A || isIntegral!A || isFloatingPoint!A) alias Meta = ScalarMeta!A; else alias Meta = AggregateMeta!A; } struct RaRMeta(A) { alias ElementType = typeof(A.init[0]); Meta!ElementType[] model; } struct ScalarMeta(A) {} struct AggregateMeta(A) { static foreach (member; __traits(allMembers, A)) mixin("Meta!(typeof(A.%1$s)) %1$s;".format(member)); } void main() { auto meta = Meta!Node(); assert(meta.value == ScalarMeta!string()); assert(meta.i == ScalarMeta!int()); assert(meta.nt == AggregateMeta!NestedType()); assert(meta.nt.s == ScalarMeta!string()); assert(meta.nt.d == ScalarMeta!double()); } ``` It works. But when I try to wrap around a recursive data type (uncomment `children` member of `Node` type) it fails because during instantiating of `Meta!Node` it needs complete `Meta!Node` type to process `children` member of `Node`. How can I "break" this recursion or some other work around to fix it?
Re: Why does this mixin fail to compile?
On 01.07.2024 15:26, ryuukk_ wrote: Ok, i'll just do it and benchmark at the end Another question: Why doesn't this work?: I'm pretty sure your code does not work the way you think it does. String Mixins and Template Mixins are two different things. If you want to use String Mixins just make a function that creates a complete string with the source code and then mix it in. No need for Template Mixins in this case. ```D string generateSourceCode(T)() { return T.stringof ~ "* ctx;"; } void main() { mixin(generateSourceCode!int); static assert(is(typeof(ctx) == int*)); assert(ctx is null); } ```
Re: Why does this mixin fail to compile?
On 01.07.2024 13:31, ryuukk_ wrote: On Monday, 1 July 2024 at 10:20:25 UTC, drug007 wrote: No problem, make a full string then mixin it. Your "no problem" = lot of string concatenation therefore slower and memory hungry, i have no desire to do that Do you think that string concatenation is the most heavy operation on using string mixin? When you pass the mixin string to the compiler it allocates memory too. If you want to use incomplete mixin strings the compiler will accumulate it (allocating additional memory) until it builds a complete AST node to mix in at once. At best, it will cost the same as building a full string as I suggested but in general it may cost even more. Also, compilation would take longer because the compiler would need to have additional logic to detect the end of your string mixin etc. Your profit from avoiding string concatenation would almost negative.
Re: Why does this mixin fail to compile?
On 01.07.2024 12:39, ryuukk_ wrote: On Monday, 1 July 2024 at 09:29:50 UTC, Dennis wrote: On Monday, 1 July 2024 at 09:25:39 UTC, ryuukk_ wrote: This simple mixin fails to compile, anyone know why? ```D mixin implement; mixin template implement() { mixin("struct _gen(T) {"); mixin("}"); } A string mixin must form a complete declaration / statement / expression / type, so you can't end on an open brace. this is sad, how i am supposed to do a foreach inbetween? ```D mixin implement!TEST; mixin template implement(stuff) { mixin("struct _gen(T) {"); // pseudo code static foreach(args) mixin("stuff"); mixin("}"); } void main(){} ``` No problem, make a full string then mixin it.
Re: SumType extraction
On 28.06.2024 15:43, Josh Holtrop wrote: On Friday, 28 June 2024 at 10:52:01 UTC, drug007 wrote: Nothing prevents that, and indeed I still plan to use item.match! like that when I need to handle multiple/all types. I just wanted the get! functionality when I only expect or want to handle one type without all the additional pattern matching syntax. But, I think my: ```d if (Foo foo = item.get!Foo) { /* do something with foo */ } ``` is still only checking the type once due to the one call to match! in get!, right? Both yes and no, you check the type once, but then check for null, so a double check is performed nonetheless. But for me it's a minor difference. There are two common ways to handle sumtypes: using either an explicit type tag or implicit type handling. Both have their pros and cons. As I know (can be wrong) std.sumtype implies type handlers not type tags.
Re: SumType extraction
What prevents you from doing: ```D import std.sumtype; class Foo {} class Bar {} alias Item = SumType!(Foo, Bar); void main() { Item[] items = [Item(new Foo()), Item(new Bar()), Item(new Foo()), Item(new Bar())]; foreach (item; items) { item.match!( (Foo v) { /* do something with foo */ }, (_) {} ); } } ``` ? It's more effective by the way - you check the type once only.
Re: How to use D without the GC ?
On 12.06.2024 23:56, bachmeier wrote: On Wednesday, 12 June 2024 at 20:37:36 UTC, drug007 wrote: On 12.06.2024 21:57, bachmeier wrote: On Wednesday, 12 June 2024 at 18:36:26 UTC, Vinod K Chandran wrote: On Wednesday, 12 June 2024 at 15:33:39 UTC, bachmeier wrote: A SafeRefCounted example with main marked @nogc: ``` import std; import core.stdc.stdlib; struct Foo { double[] data; double * ptr; alias data this; @nogc this(int n) { ptr = cast(double*) malloc(n*double.sizeof); data = ptr[0..n]; printf("Data has been allocated\n"); } } ``` Why not just use `ptr` ? Why did you `data` with `ptr` ? Try `foo[10] = 1.5` and `foo.ptr[10] = 1.5`. The first correctly throws an out of bounds error. The second gives `Segmentation fault (core dumped)`. I think you can use data only because data contains data.ptr Yes, but you get all the benefits of `double[]` for free if you do it that way, including the more concise foo[10] syntax. I meant you do not need to add `ptr` field at all ```D import std; import core.stdc.stdlib; struct Foo { @nogc: double[] data; alias data this; this(int n) { auto ptr = cast(double*) malloc(n*double.sizeof); data = ptr[0..n]; } } @nogc void main() { auto foo = SafeRefCounted!Foo(3); foo[0..3] = 1.5; printf("%f %f %f\n", foo[0], foo[1], foo[2]); foo.ptr[10] = 1.5; // no need for separate ptr field } ```
Re: How to use D without the GC ?
On 12.06.2024 21:57, bachmeier wrote: On Wednesday, 12 June 2024 at 18:36:26 UTC, Vinod K Chandran wrote: On Wednesday, 12 June 2024 at 15:33:39 UTC, bachmeier wrote: A SafeRefCounted example with main marked @nogc: ``` import std; import core.stdc.stdlib; struct Foo { double[] data; double * ptr; alias data this; @nogc this(int n) { ptr = cast(double*) malloc(n*double.sizeof); data = ptr[0..n]; printf("Data has been allocated\n"); } } ``` Why not just use `ptr` ? Why did you `data` with `ptr` ? Try `foo[10] = 1.5` and `foo.ptr[10] = 1.5`. The first correctly throws an out of bounds error. The second gives `Segmentation fault (core dumped)`. I think you can use data only because data contains data.ptr
Re: How to use D without the GC ?
On 11.06.2024 17:59, Kagamin wrote: 1) arena allocator makes memory manageable with occasional cache invalidation problem 2) no hashtable no problem [OT] could you elaborate what problems they cause? 3) error handling depends on your code complexity, but even in complex C# code I found exceptions as boolean: you either have an exception or you don't 4) I occasionally use CTFE, where `@nogc` is a nuisance 5) polymorphism can be a little quirky
Re: How to generate a random number from system clock as seed
On 09.06.2024 16:37, Eric P626 wrote: On Saturday, 8 June 2024 at 18:25:20 UTC, drug007 wrote: ~~~ { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ~~~ I managed to use this piece of code and it worked. ~~~ uint seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); ~~~ I am not exactly sure what the exclamation points stand for in the first line of code. Probably, defining a type to class ```castFrom``` and function ```to```. But I get the idea that it just cast long to uint since ```Random``` requires an unsigned int > I assume from this line of code that C casting like ```(uint)varname``` would not work. `CastFrom!long` is a template instantiation. The instantiated template converts from `long` to `uint`. It is useful in meta-programming but here you can safely use other forms like c style cast: ```d const seed = cast(uint) Clock.currStdTime; ``` or ``` const seed = to!uint(Clock.currStdTime & 0x); ``` here we need to use the `0x` mask, because `to!uint` throws a conversion positive overflow when the value of `Clock.currStdTime` exceeds the value of `uint.max`. But I don't like this variant and I don't recommend it.
Re: How to generate a random number from system clock as seed
On 08.06.2024 16:19, Eric P626 wrote: I managed to create a random number generator using the following code: ~~~ auto rng = Random(42); // uniform(0,10,rng); ~~~ Now I want to seed the generator using system time. I looked at Date & time functions/classes and systime functions/classes. The problem is that they all require a time zone. But I don't need a time zone since there is no time zone. I just want the number of seconds elapsed since jan 1st 1970. In other words, the internal system clock value. ```d import std; void main() { { auto rng = Random(42); auto result = generate!(() => uniform(0, 10, rng))().take(7); // the same random numbers sequence assert (result.equal([2, 7, 6, 4, 6, 5, 0])); } { const seed = castFrom!long.to!uint(Clock.currStdTime); auto rng = Random(seed); auto result = generate!(() => uniform(0, 10, rng))().take(7); // new random numbers sequence every time result.writeln; } } ```
Re: Recommendation on plotting library
20.07.2023 05:37, Chris Piker пишет: Hi D One of my jobs is to release and maintain public data archives from long-running scientific instruments. In order to help people understand how to process the data, sample code is often included with the archive. Recently this has been in the form of short programs that generate a plot of a representative time period. Python works well for this task as matplotlib support is pretty much universal. Matlab is also a reasonable choice for many. Were I to also provide sample code in D, what library would you recommend for scientific plotting, especially for dynamic power spectral densities generated from time-series data (basically heatmaps)? Since dub can pull down dependencies easily enough and since it supports single file projects it seems that D would be well suited to this task, but I've never plotted any data directly from a D program. Many GUI libraries I see for D are wrappers around external C or C++ based libraries that would need to be installed separately. I'd like to avoid such complications if that's possible. Thanks for any advice, https://code.dlang.org/packages/ggplotd
Re: How to free memory ater use of "new" to allocate it.
17.07.2023 15:45, Alain De Vos пишет: This works also: [snipped] Despite this time you use new you still allocate your class on stack using scope and its scope still is `dofun`. But I just want to inform you. Your solutions work. Don't get me wrong. N.B. I would say if you do not have THE reason to manually free memory - do not do this. At all. Just let GC does its work.
Re: How to free memory ater use of "new" to allocate it.
17.07.2023 13:17, Alain De Vos пишет: The following code works: ``` import std.stdio:writefln; import object: destroy; import core.memory: GC; import core.stdc.stdlib: malloc,free; import std.typecons; class C { int * pa; int [] a; // Constructor this() {writefln("Called constructor"); pa=cast(int *)malloc(1000*int.sizeof); a=pa[0..1000]; } ~this(){ writefln("Called Destructor"); free(a.ptr);} } void dofun() { auto x=scoped!(C); x.a[3]=5; writefln("%12x",); } int main(){ dofun(); dofun(); return 0; } ``` Note that you do not use new anymore. You allocate your class instances on stack and their scope is `dofun()` only
Re: How get struct value by member name string ?
30.05.2023 11:46, John Xu пишет: How to put above enum as a function parameter? Following code wouldn't work: string getTMember(T t, enum string memberName) { return __traits(getMember, t, memberName); } My database table is very wide, with many columns. Above ddbc allows a struct to map db returned data. Then if I want a member's value to show in vibe.d template, how do I use a function to get it? This works for me: ```D import std; void main() { struct T {int a; string name;} auto t = T(12, "got by member name"); enum s = "name"; writeln(__traits(getMember, t, s)); } ```
Re: Coding Challenges - Dlang or Generic
10.01.2023 14:23, drug007 пишет: 10.01.2023 13:57, matheus пишет: On Tuesday, 10 January 2023 at 05:21:15 UTC, H. S. Teoh wrote: Printing it in this format is trivial, and not very interesting. The interest in the challenge is to lay it out like I posted, side-by-side,... Like I said I did it over D online compiler which unfortunately I couldn't validate the output because it "wraps" the text, and the font wasn't monospace. But It just a case of changing the loop in a way to print 3 groups of months. ... and to do so in a way that the code is clean, maintainable, and consists of reusable components. ... Talking about modularity and reusable components, I really think it depends, because if that's was really the case, then I would think of using the OS functions to move the cursor around (If console/terminal) to print a given month in some location or side by side until reach some horizontal limit (Terminal), then it could be 1 column only (Like I did), 2, 3 and maybe 4 columns if the terminal/resolution permit, and for that I would use ARSD. :] But I think this would be too much for this kind of thing writing on online compiler. ... That's where the challenge lies. To be honest when I saw your proposal, I really thought that the real challenge would be to write my own algo to handle the date, and I was pretty sure after posting above, you would say that, but not about the layout or printing in groups. =] Matheus. [To clarify the situation](https://wiki.dlang.org/Component_programming_with_ranges) (H S Teoh is the author of this article) Also I'd like to add that this article inspired Eric Niebler to write ranges for C++. Now C++ has already 3rd version of ranges and they are still not used in general.
Re: Coding Challenges - Dlang or Generic
10.01.2023 13:57, matheus пишет: On Tuesday, 10 January 2023 at 05:21:15 UTC, H. S. Teoh wrote: Printing it in this format is trivial, and not very interesting. The interest in the challenge is to lay it out like I posted, side-by-side,... Like I said I did it over D online compiler which unfortunately I couldn't validate the output because it "wraps" the text, and the font wasn't monospace. But It just a case of changing the loop in a way to print 3 groups of months. ... and to do so in a way that the code is clean, maintainable, and consists of reusable components. ... Talking about modularity and reusable components, I really think it depends, because if that's was really the case, then I would think of using the OS functions to move the cursor around (If console/terminal) to print a given month in some location or side by side until reach some horizontal limit (Terminal), then it could be 1 column only (Like I did), 2, 3 and maybe 4 columns if the terminal/resolution permit, and for that I would use ARSD. :] But I think this would be too much for this kind of thing writing on online compiler. ... That's where the challenge lies. To be honest when I saw your proposal, I really thought that the real challenge would be to write my own algo to handle the date, and I was pretty sure after posting above, you would say that, but not about the layout or printing in groups. =] Matheus. [To clarify the situation](https://wiki.dlang.org/Component_programming_with_ranges) (H S Teoh is the author of this article)
Re: Is `void` the correct way to say "do not initialize this variable"?
On 10/3/22 09:35, tsbockman wrote: On Sunday, 2 October 2022 at 23:45:45 UTC, drug007 wrote: It works but not as someone could expect. In case of ```D Foo[2] arr = void; ``` `arr` value is not defined, it is not an initialized array of uninitialized elements like you want, it is just uninitialized array. This is incorrect. It is not possible to declare an uninitialized static array variable in D; only the elements are affected by `= void`. The meta data of a static array like `Foo[2] arr` (`.ptr` and `.length`) is determined statically at compile time and inserted where needed into the generated code. It is not stored in mutable memory the way a dynamic array/slice's meta data is, and does not need to be initialized at run time. You are right. I used to complex structure (with indirections) for testing and made wrong statement. By contrast, it **is** possible to declare a completely uninitialized dynamic array, or to just leave its elements uninitialized: ```D // Meta data is not initialized, and no elements are allocated. // This has no static array equivalent: int[] arrA = void; // Meta data is initialized, and elements are allocated but not initialized. // This is the dynamic equivalent of the static: // int[2] arr = void; int[] arrB = uninitializedArray!(int[])(2); ```
Re: Is `void` the correct way to say "do not initialize this variable"?
On 10/3/22 02:30, ryuukk_ wrote: I have tried to look at the documentation and various places on the DMD source, but i couldn't find the answer https://dlang.org/spec/declaration.html#void_init ```D MyStruct test = void; ``` Does this guarantee that the compiler will not initialize it? Yes Does it work with static arrays of struct too? It works but not as someone could expect. In case of ``` Foo[2] arr = void; ``` `arr` value is not defined, it is not an initialized array of uninitialized elements like you want, it is just uninitialized array. The generated code is different than ``MyStruct test;`` What exactly (by exactly i mean is the behavior documented somewhere?) ``void`` does?
Re: std.container.array.Array is not @nogc?
On 15.01.2017 15:49, Jack Stouffer wrote: No you're not. Array was designed before the @nogc attribute was created, so it wasn't coded with it's requirements in mind. Looking at the code, Array allocates GC memory for exception throwing in some cases. These can and should be changed to asserts. I am writing a PR now to fix this. There doesn't seem to be too many cases to fix. Thanks for answer. Looking forward for your PR.
std.container.array.Array is not @nogc?
Is there a way to use Array in @nogc code: ``` import std.container.array : Array; @nogc: void main(string[ ] args) { Array!int ai; ai ~= 1; assert(ai[0] == 1); } ``` fails: ``` main.d(8): Error: @nogc function 'D main' cannot call non-@nogc function 'std.container.array.Array!int.Array.opOpAssign!("~", int).opOpAssign' main.d(9): Error: @nogc function 'D main' cannot call non-@nogc function 'std.container.array.Array!int.Array.opIndex' ``` am I doing something wrong?
Re: Accessing members through pointers to structs (also, CTFE associative arrays)
On 13.12.2016 23:30, Ali wrote: Hi, Long time watcher and recently started playing with D a bit more. Ran in to a couple of snags that I'll combine in one post. It involves a data set that contains a list of strings. Each string represents a Room name. What I'm trying to do is pluck out the room names and also calculate the frequency each letter occurs in a name, per room. First problem is to do with pointers to structs. Here's the code: static immutable rooms = import("data.txt").split("\n").map!parse.array; static Tuple!(const(Room*), "room", int[char], "frequencies")[rooms.length] data; static this() { foreach (i, room; rooms) { data[i].room = // Also calculate frequencies, but that's not important yet. } } void main() { foreach (d; data) { d.room.name.writeln; // <-- How do I access name here?? } } I've tried d.(*room).name but that didn't work. There's no arrow I'm sleepy, sorry for quick and probable wrong answer - try (*d.room).name
Re: Using the result of a comma expression is deprecated
On 27.11.2016 14:07, Suliman wrote: I am getting deprecation message: "Using the result of a comma expression is deprecated" on this code: string sqlinsert = (`INSERT INTO usersshapes (userlogin, uploading_date, geometry_type, data) VALUES ('%s', '%s', '%s', '%s') `, login, uploading_date, geometry_type, data); What's wrong with it? Didn't you miss something like class/structure/function before "(`INSERT..."? What result do you expect?
Re: How do i convert this Makefile to dub
On 08.08.2016 21:48, Adil wrote: On Monday, 8 August 2016 at 18:45:35 UTC, drug007 wrote: On 08.08.2016 21:35, Adil wrote: On Monday, 8 August 2016 at 18:29:54 UTC, Adil wrote: [...] One minor addition. I use the Makefile in our CI tool, that inserts auto-increment numbers in place of git hashes. Numbers are a familiar. Ex: make VERSION_STRING=v%build.number%; make screener-d-debug VERSION_STRING=v%build.number%; Can i insert a version number when i run dub? You can do it by using `preBuildCommands` in dub.sdl, see http://code.dlang.org/package-format?lang=sdl How can i pass a VERSION_STRING from the cmd line? I don't know about passing from cli, but you can redirect output to some .d file and import it, for example.
Re: How do i convert this Makefile to dub
On 08.08.2016 21:35, Adil wrote: On Monday, 8 August 2016 at 18:29:54 UTC, Adil wrote: I have a Makefile setup that I use to return the latest git tag/commit from within my program. The setup is as below: VERSIONED_LIB = myversion.d && rm -f myversion.d VERSION_STRING ?= $(shell git rev-parse --short HEAD) makeVersion: echo "module compileConfig; public string versionString = \"$(VERSION_STRING)\";" > myversion.d; mysoftware: makeVersion dmd -de -O /* compiler flags */ source/myprogrma.d myversion.d rm -f myversion.d When i run `make mysoftware` my binary now contains the latest git commit HASH, which i use for debugging. How can i mimic the same setup i dub? Is there an alternative to achieve the same goal? One minor addition. I use the Makefile in our CI tool, that inserts auto-increment numbers in place of git hashes. Numbers are a familiar. Ex: make VERSION_STRING=v%build.number%; make screener-d-debug VERSION_STRING=v%build.number%; Can i insert a version number when i run dub? You can do it by using `preBuildCommands` in dub.sdl, see http://code.dlang.org/package-format?lang=sdl
Re: Array of const objects with indirections and std.algorithm.copy
On 28.07.2016 21:45, Ali Çehreli wrote: On 07/27/2016 04:51 AM, drug wrote: > cfoo.copy(foo); // fails to compile because phobos in case of array uses > // array specialization and this specialization fails > // see > https://github.com/dlang/phobos/blob/v2.071.1/std/algorithm/mutation.d#L333 Thanks for explaining further. Yes, this is a bug. Although areCopyCompatibleArrays!(const(Foo)[], Foo[]) is true, std.algorithm.copy of that specialization fails. Please create a bug report at https://issues.dlang.org/ Thank you, Ali Thank you too. done https://issues.dlang.org/show_bug.cgi?id=16332