Re: Associative Array with double[][]
On Thursday, 22 July 2021 at 04:46:13 UTC, frame wrote: Of course a double* makes more sense than a void* type for the AA here.
Re: Associative Array with double[][]
On Thursday, 22 July 2021 at 03:13:14 UTC, seany wrote: If there are multiple possibilities, what is the fastest in terms of memory? Thank you. I believe the fastest way (as seen from your loop) would be using pointer arithmetric and using void* keys for diagonalLengths and an index function that is able to pick the void* key/address from the given double coordinates. You may also consider using a binary tree data structure instead of AA.
Re: enum true, or 1
On 7/21/21 8:44 PM, Brian Tiffin wrote: > What is the preferred syntax for simple on/off states? I use std.typecons.Flag. It feels very repetitive but that's what we have: import std.typecons; void foo(Flag!"doFilter" doFilter) { if (doFilter) { // ... } } bool someCondition; void main() { // Literal values of Flag!"doFilter" foo(Yes.doFilter); foo(No.doFilter); // Assuming we start with an existing 'bool'... bool doFilter = someCondition; // ... I like this helper (see below): foo(flagFromBool!doFilter); } template flagFromBool(alias variable) { enum flagName = variable.stringof; auto flagFromBool() { import std.format : format; enum expr = format!q{ return variable ? Yes.%s : No.%s; }(flagName, flagName); mixin (expr); } } > Did I read that > D was moving to strictly 1 and 0 literals instead of true/false on/off > yes/no? Walter sees 'bool' as a 1-bit integer type. I can't. :) I cringe everytime I see assert(0). To me, it is assert(false); :/ > If so, is there an idiom for yes/no/maybe -1,0,1 less/equal/greater? opCmp's return value has three states: < 0 == 0 > 0 Ali
Re: enum true, or 1
On 22/07/2021 3:44 PM, Brian Tiffin wrote: What is the preferred syntax for simple on/off states? Did I read that D was moving to strictly 1 and 0 literals instead of true/false on/off yes/no? This is the first time I'm hearing about it, so almost certainly no.
Re: enum true, or 1
On Thursday, 22 July 2021 at 03:44:13 UTC, Brian Tiffin wrote: What is the preferred syntax for simple on/off states? Did I read that D was moving to strictly 1 and 0 literals instead of true/false on/off yes/no? If so, is there an idiom for yes/no/maybe -1,0,1 less/equal/greater? Excuse the noise. For some backfill; getting used to DDoc. Frontmatter can be attached to the module declaration. Great for setting up a page. Wanted to do something similar for backmatter, in particular the without warranty disclaimer (instead of it taking up space on the first screen of a listing). That means attaching backmatter doc comments to a declaration, something akin to `enum INDEMNITY = true;`. Or is it `= 1`? Opinions welcome, as this will end up being nothing more than a personal preference, but it would be nice to avoid dragging fingernails over anyone's mental chalkboard. Have good, make well. AFAIK, the usual wisdom is to use `true` or `false` over `1` and `0`. However, it still might not be enough in a public API, so there is `std.typecons.Flag`: https://dlang.org/library/std/typecons/flag.html Last but not least, `true` is defined as `1` per the spec, so the following is valid: ``` char[] myString = getString(); bool hasNullCharAtEnd = parseString(myString); char[] copy = new char[](myString.length - hasNullCharAtEnd); ``` This is quite useful when needed to offset something by one: Just add or subtract your `bool` value.
issue with static foreach
The following code chunk compiles perfectly: ```d labelSwitch: switch (lstrExchangeID) { static foreach (sstrExchangeID; gstrExchangeIDs) { mixin(r"case r"d, `"`, sstrExchangeID, `"`, r"d : "d); mixin(r"classTickerCustom"d, sstrExchangeID, r" lobjTicker"d, sstrExchangeID, r" = new classTickerCustom"d, sstrExchangeID, r"(lstrSymbolID);"d); //mixin(r"if (true == true) {"d); mixin(r"pobjTickersCustom"d, sstrExchangeID, r" ~= lobjTicker"d, sstrExchangeID, r";"d); mixin(r"pobjTickersCommon ~= cast(classTickerCommon) lobjTicker"d, sstrExchangeID, r";"d); //mixin(r"}"d); mixin(r"break labelSwitch;"d); } default : break; } ``` Now, if uncomment those two innocuous commented lines for the if (true == true) block: ```d labelSwitch: switch (lstrExchangeID) { static foreach (sstrExchangeID; gstrExchangeIDs) { mixin(r"case r"d, `"`, sstrExchangeID, `"`, r"d : "d); mixin(r"classTickerCustom"d, sstrExchangeID, r" lobjTicker"d, sstrExchangeID, r" = new classTickerCustom"d, sstrExchangeID, r"(lstrSymbolID);"d); mixin(r"if (true == true) {"d); mixin(r"pobjTickersCustom"d, sstrExchangeID, r" ~= lobjTicker"d, sstrExchangeID, r";"d); mixin(r"pobjTickersCommon ~= cast(classTickerCommon) lobjTicker"d, sstrExchangeID, r";"d); mixin(r"}"d); mixin(r"break labelSwitch;"d); } default : break; } ``` ... it compiles no-more: Error: found `End of File` when expecting `}` following compound statement ... what I am doing wrong ?
enum true, or 1
What is the preferred syntax for simple on/off states? Did I read that D was moving to strictly 1 and 0 literals instead of true/false on/off yes/no? If so, is there an idiom for yes/no/maybe -1,0,1 less/equal/greater? Excuse the noise. For some backfill; getting used to DDoc. Frontmatter can be attached to the module declaration. Great for setting up a page. Wanted to do something similar for backmatter, in particular the without warranty disclaimer (instead of it taking up space on the first screen of a listing). That means attaching backmatter doc comments to a declaration, something akin to `enum INDEMNITY = true;`. Or is it `= 1`? Opinions welcome, as this will end up being nothing more than a personal preference, but it would be nice to avoid dragging fingernails over anyone's mental chalkboard. Have good, make well.
Re: Performance issue with fiber
On Wednesday, 21 July 2021 at 22:51:38 UTC, hanabi1224 wrote: Hi, I'm new to D lang and encounter some performance issues with fiber, not sure if there's something obviously wrong with my code. [...] Following. I am also in need of more information to increase speed of D binaries using parallel code.
Associative Array with double[][]
I have a perimeter of a shape, given by a `double [][]` . I want to keep the lengths of various diagonals in another associative array. So, /// define some associative array to keep track of diagonals here.. auto perimeter = new double[][] (0,0); /// --- fill up perimeter here --- for(int i = 0; i < perimeter.length; i++) { for ( int j = 0; j < perimeter.length; j++) { fill up the associative array here } } So, I would like to do this: double[ double[][]] diagonalLengths; auto perimeter = new double[][] (0,0); /// --- fill up perimeter here --- for(int i = 0; i < perimeter.length; i++) { for ( int j = 0; j < perimeter.length; j++) { auto diag_point_i = perimeter[i]; auto diag_point_j = perimeter[j]; diagonalLengths [ [diag_point_i, diag_point_j]] = calculate_length (i,j); } } This is necessary, as further processing will change the indices of the points in the perimeter. I can't therefore use ` diagonalLengths [ [i,j]] = calculate_length (i,j);` However, trying to do this is resulting to : `test.d(29): Error: associative arrays can only be assigned values with immutable keys, not `double[][]` What are my options now? Do I have to convert the array which i plan to use as a key to a struct and define opEquals and toHash? Are there automatic hashing mechanisms for this? If there are multiple possibilities, what is the fastest in terms of memory? Thank you.
Performance issue with fiber
Hi, I'm new to D lang and encounter some performance issues with fiber, not sure if there's something obviously wrong with my code. Basically, I found D lang's logical thread communication is quite like Elixir's (process), I have programs written in both D and Elixir but the D version (release build) is like >5 times slower. The program is to find first N primes by creating another coroutine for every prime found. And the idea is from the concurrent prime sieve example on golang's homepage. Elixir code: [1.ex](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/coro-prime-sieve/1.ex) D code: [1.d](https://github.com/hanabi1224/Programming-Language-Benchmarks/blob/main/bench/algorithm/coro-prime-sieve/1.d) Perf result of calculating first 2000 primes on my laptop. Elixir: 1.33s user 0.25s system 108% cpu 1.451 total D(dmd): 10.41s user 34.48s system 361% cpu 12.405 total D(ldc): 8.45s user 33.06s system 356% cpu 11.638 total Also attaching code inline: D ```d import std; import core.stdc.stdlib: exit; __gshared Tid mainTid; __gshared bool terminated = false; const int mailBoxSize = 1; void main(string[] args) { auto n = args.length > 1 ? args[1].to!int() : 10; auto scheduler = new FiberScheduler; scheduler.start({ mainTid = thisTid(); setMaxMailboxSize(mainTid, n, OnCrowding.throwException); auto filterTid = spawnLinked(, n); setMaxMailboxSize(filterTid, mailBoxSize, OnCrowding.block); auto generatorTid = spawnLinked(, filterTid); for(auto i=0;i 0) { filterInner(prime, nLeft); } } void filterInner(int prime, int nLeft) { auto nextTid = spawnLinked(, nLeft-1); setMaxMailboxSize(nextTid, mailBoxSize, OnCrowding.block); while(!terminated){ auto d = receiveOnly!int; if (d % prime != 0) { nextTid.send(d); } } } ``` Elixir ```elixir defmodule App do def main(args) do n = String.to_integer(Enum.at(args,0,"27"), 10) generate(n) end def generate(n) do mainPid = self() pid = spawn_link(fn -> filter(mainPid, n) end) generateLoop(pid, 2) end def generateLoop(pid, n) do send(pid, {:n, n}) receive do :gen -> generateLoop(pid, n + 1) end end def filter(mainPid, nLeft) do receive do {:n, n} -> filterInner(mainPid, n, nLeft) end end def filterInner(mainPid, prime, nLeft) do send(mainPid, :gen) IO.puts("#{prime}") if nLeft > 1 do pid = spawn_link(fn -> filter(mainPid, nLeft-1) end) recieveAndSendToFilter(mainPid, self(), pid, prime) else System.halt(0) end end def recieveAndSendToFilter(mainPid, rxPid, txPid, prime) do receive do {:n, n} -> recieveAndSendToFilterInner(mainPid, rxPid, txPid, prime, n) end end def recieveAndSendToFilterInner(mainPid, rxPid, txPid, prime, n) do if Integer.mod(n, prime) != 0 do send(txPid, {:n, n}) else send(mainPid, :gen) end recieveAndSendToFilter(mainPid, rxPid, txPid, prime) end end ```
Re: How to Fix Weird Build Failure with "-release" but OK with "-debug"?
On Wednesday, 21 July 2021 at 14:15:51 UTC, Steven Schveighoffer wrote: 2. It's hard for me to see where the null dereference would be in that function (the `bool` implementation is pretty simple). -Steve DMD complains about dereferences in three different lines. I suspect it's `this` reference that is `null`.
Re: Method definition
On Wednesday, 21 July 2021 at 14:02:42 UTC, Adam D Ruppe wrote: On Wednesday, 21 July 2021 at 13:56:11 UTC, Tim Gunesh wrote: This allows you to quickly understand the content of the class, especially in large undocumented projects. The D compiler can auto-generate listings like that. dmd -H makes a .di file with the bodies stripped out you can pursue, or a documentation generator like my adrdox can make HTML files with the method prototypes, even if there are no other docs (use --document-undocumented arg to adrdox for that). So you can accomplish these goals through other means. Lots of thanks Adam! I'm new to D and this is the language I fell in love with the first time :). And tools like yours (https://github.com/adamdruppe/adrdox) are important to me.
Re: How to Fix Weird Build Failure with "-release" but OK with "-debug"?
On 7/21/21 7:56 AM, apz28 wrote: On Wednesday, 21 July 2021 at 11:52:39 UTC, apz28 wrote: On Wednesday, 21 July 2021 at 04:52:44 UTC, Mathias LANG wrote: It seems the compiler is doing extra analysis and seeing that a null pointer is being dereferenced. Can you provide the code for "pham\db\db_skdatabase.d" at L138 through 140 ? ```d package(pham.db): // Line# 133 final DbReadBuffer acquireSocketReadBuffer(size_t capacity = DbDefaultSize.socketReadBufferLength) nothrow @safe { version (TraceFunction) dgFunctionTrace(); if (_socketReadBuffer is null) _socketReadBuffer = createSocketReadBuffer(capacity); return _socketReadBuffer; } ``` The entire codes is available from github https://github.com/apz28/dlang/blob/main/source/pham/db/db_skdatabase.d#L138 1. That filename is totally wrong, or the function name is totally wrong. ddemangle says the function is `@safe bool[] pham.db.fbdatabase.FbArray.readArrayImpl!(bool).readArrayImpl(pham.db.database.DbNameColumn)` which seems to be located [here](https://github.com/apz28/dlang/blob/02989b94bfe306d723f2780e010c61f71f873cbe/source/pham/db/db_fbdatabase.d#L142) But the line numbers also don't match. maybe an inlining issue? 2. It's hard for me to see where the null dereference would be in that function (the `bool` implementation is pretty simple). -Steve
Re: Method definition
On Wednesday, 21 July 2021 at 13:56:11 UTC, Tim Gunesh wrote: This allows you to quickly understand the content of the class, especially in large undocumented projects. The D compiler can auto-generate listings like that. dmd -H makes a .di file with the bodies stripped out you can pursue, or a documentation generator like my adrdox can make HTML files with the method prototypes, even if there are no other docs (use --document-undocumented arg to adrdox for that). So you can accomplish these goals through other means.
Re: betterC shared static ctor
On 7/21/21 5:07 AM, vit wrote: Thanks, it works, but now I have different problem. I need call static method for all instantions of template struct from `crt_constructor`. Is there way to iterate over all instantions of template? Not unless you register them somehow upon instantiation. Or (I think) you can implement the constructor as a static method, and tag it with `pragma(crt_constructor)`. Then it gets added when instantiated. -Steve
Re: Method definition
On Wednesday, 21 July 2021 at 12:08:21 UTC, Tim Gunesh wrote: Is it possible to define methods outside the class in C ++ style? Something like this: ```d class Parent{ void Print(); } void Parent.Print(){ writeln("Hello, D!"); } ``` I was afraid that this is not possible. I'm partly used to this convenience in C++. This allows you to quickly understand the content of the class, especially in large undocumented projects. I'd love to move this to D. Thanks everyone for the reply and thanks to Paul Backus for an alternative way of defining methods!
Re: How to parse a json node that contains children of different types?
On 7/20/21 11:00 PM, Mathias LANG wrote: But if you take a step back, I think you might find this solution is far from ideal. Having worked on a JSON library myself, I can tell you they are all implemented with a tagged union. And converting a tagged union to a tagged union is no improvement. Not [jsoniopipe](https://github.com/schveiguy/jsoniopipe). In that case, you could use a specialized type with a `fromJSON` static member to do whatever you wanted. -Steve
Re: Yet another parallel foreach + continue question
On 7/19/21 10:58 PM, H. S. Teoh wrote: I didn't check the implementation to verify this, but I'm pretty sure `break`, `continue`, etc., in the parallel foreach body does not change which iteration gets run or not. `break` should be undefined behavior (it is impossible to know which loops have already executed by that point). `continue` should be fine. Noted in the [docs](https://dlang.org/phobos/std_parallelism.html#.TaskPool.parallel): Breaking from a parallel foreach loop via a break, labeled break, labeled continue, return or goto statement throws a ParallelForeachError. I would say `continue` is ok (probably just implemented as an early return), but all those others are going to throw an error (unrecoverable). -Steve
Re: How to Fix Weird Build Failure with "-release" but OK with "-debug"?
On Wednesday, 21 July 2021 at 03:25:03 UTC, apz28 wrote: VisualD project - Any hint to work around DMD version: DMD32 D Compiler v2.096.0-rc.1-dirty Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved written by Walter Bright Failed Build Command line: dmd -release -m32mscoff -O -inline -dip25 -dip1000 -preview=fixAliasThis -X -Xf"Win32\Release\db_library.json" -c -of"Win32\Release\db_library.obj" @Win32\Release\db_library.build.rsp with below error message: ..\..\pham\db\db_skdatabase.d(140): Error: null dereference in function _D4pham2db10fbdatabase7FbArray__T13readArrayImplTbZQsMFNfCQCeQCc8database12DbNameColumnZAb ..\..\pham\db\db_skdatabase.d(139): Error: null dereference in function _D4pham2db10fbdatabase7FbArray__T13readArrayImplTbZQsMFNfCQCeQCc8database12DbNameColumnZAb Error: null dereference in function _D4pham2db10fbdatabase7FbArray__T13readArrayImplTbZQsMFNfCQCeQCc8database12DbNameColumnZAb ..\..\pham\db\db_skdatabase.d(138): Error: null dereference in function _D4pham2db10fbdatabase7FbArray__T13readArrayImplTbZQsMFNfCQCeQCc8database12DbNameColumnZAb The problem here is not actually -release but -O. -O will check for null derefences in your code when using @safe I believe. I didn't inspect your code much further, as I'm short on time right now, but you should have a starting point now at least.
Re: Method definition
On Wednesday, 21 July 2021 at 12:08:21 UTC, Tim Gunesh wrote: Is it possible to define methods outside the class in C ++ style? Something like this: ```d class Parent{ void Print(); } void Parent.Print(){ writeln("Hello, D!"); } ``` No and it doesn't make much sense to do so. The reason why you have to do in C++ is because of header files and source files are separate. Since D uses modules then definition and implementation doesn't have to be separated.
Re: Method definition
On Wednesday, 21 July 2021 at 12:08:21 UTC, Tim Gunesh wrote: Is it possible to define methods outside the class in C ++ style? Something like this: ```d class Parent{ void Print(); } void Parent.Print(){ writeln("Hello, D!"); } ``` No, it's not possible. However, [uniform function call syntax][1] allows functions defined outside of a class to be called as though they were methods. For example: ```d class Parent {} void Print(Parent p) { writeln("Hello, D!"); } void example() { Parent p = new Parent; p.Print(); // passes `p` as first argument } ``` [1]: https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs
Method definition
Is it possible to define methods outside the class in C ++ style? Something like this: ```d class Parent{ void Print(); } void Parent.Print(){ writeln("Hello, D!"); } ```
Re: How to Fix Weird Build Failure with "-release" but OK with "-debug"?
On Wednesday, 21 July 2021 at 11:52:39 UTC, apz28 wrote: On Wednesday, 21 July 2021 at 04:52:44 UTC, Mathias LANG wrote: It seems the compiler is doing extra analysis and seeing that a null pointer is being dereferenced. Can you provide the code for "pham\db\db_skdatabase.d" at L138 through 140 ? ```d package(pham.db): // Line# 133 final DbReadBuffer acquireSocketReadBuffer(size_t capacity = DbDefaultSize.socketReadBufferLength) nothrow @safe { version (TraceFunction) dgFunctionTrace(); if (_socketReadBuffer is null) _socketReadBuffer = createSocketReadBuffer(capacity); return _socketReadBuffer; } ``` The entire codes is available from github https://github.com/apz28/dlang/blob/main/source/pham/db/db_skdatabase.d#L138
Re: How to Fix Weird Build Failure with "-release" but OK with "-debug"?
On Wednesday, 21 July 2021 at 04:52:44 UTC, Mathias LANG wrote: It seems the compiler is doing extra analysis and seeing that a null pointer is being dereferenced. Can you provide the code for "pham\db\db_skdatabase.d" at L138 through 140 ? ```d package(pham.db): // Line# 133 final DbReadBuffer acquireSocketReadBuffer(size_t capacity = DbDefaultSize.socketReadBufferLength) nothrow @safe { version (TraceFunction) dgFunctionTrace(); if (_socketReadBuffer is null) _socketReadBuffer = createSocketReadBuffer(capacity); return _socketReadBuffer; } ```
Re: Initializing a complex dynamic array (with real part from one array, and imaginary from other array)?
I wouldn't state it is the best way but you can try something like that: ```D import std.complex; import std.range : zip; import std.algorithm : equal, map; import std.array : array; void main(){ auto N=2; double[] x,y; x.length = N; y.length = N; x[0] = 1.1; x[1] = 2.2; y[0] = 3.3; y[1] = 4.4; auto z = zip(x, y) // concatenate two ranges .map!(a=>Complex!double(a[0],a[1])) // take the current first element of the first range as the real part and the current first element of the second range as the imaginary part .array; // convert the lazy range to a dynamic array, probably you can avoid but this depends on how you use it later assert(z.equal([ Complex!double(1.1, 3.3), Complex!double(2.2, 4.4), ])); } ```D
Re: betterC shared static ctor
On Wednesday, 21 July 2021 at 08:28:22 UTC, Mike Parker wrote: On Wednesday, 21 July 2021 at 08:11:06 UTC, vit wrote: Is it possible to call all shared static ctors in betterC? ```d //-betterC static immutable int i; shared static this(){ i = 42; } extern(C) void main(){ assert(i != 42); } ``` These rely on DRuntime, which is not linked in betterC mode. You'll need to use the `crt_constructor` and `crt_destructor` pragmas: https://dlang.org/spec/pragma.html#crtctor Apply them to any `extern(C) function for static ctor/dtor behavior. Thanks, it works, but now I have different problem. I need call static method for all instantions of template struct from `crt_constructor`. Is there way to iterate over all instantions of template? I need this to work but for all instantions of Foo, not only for Foo!1 a Foo!2 https://run.dlang.io/is/FNqHWh : ```d pragma(crt_constructor) extern(C)void shared_static_this(){ Foo!1.vtable_init(); Foo!2.vtable_init(); //Foo!3.vtable_init(); } extern(C) void main(){ auto foo1 = Foo!1(null); auto foo2 = Foo!2(null); auto foo3 = Foo!3(null); Base* b1 = Base* b2 = Base* b3 = assert(b1.getId() == 1); assert(b2.getId() == 2); //assert(b3.getId() == 3); //vtable is not initialized } struct Vtable{ size_t offset; size_t function(void* ) getId; } struct Base{ immutable Vtable* vptr; this(immutable Vtable* vptr){ assert(vptr !is null); this.vptr = vptr; } size_t getId(){ return vptr.getId((cast(void*)) - vptr.offset); } } struct Foo(size_t id){ static immutable Vtable vtable; Base base; this(typeof(null) nil){ this.base = Base(); } static size_t virtual_getId(Foo* foo){ return id; } static void vtable_init(){ Vtable* vtable = cast(Vtable*) vtable.offset = base.offsetof; vtable.getId = cast(typeof(Vtable.getId))_getId; } } ```
Initializing a complex dynamic array (with real part from one array, and imaginary from other array)?
I am trying to initialize a complex dynamic array, from two strictly real dynamic arrays (one to be the real part, the other to be the imaginary part. Here is simple sample of what I have tried: - import std.stdio; import std.math; import std.complex; void main(){ auto N=2; double[] x,y; x.length = N; y.length = N; x[0] = 1.1; x[1] = 2.2; y[0] = 3.3; y[1] = 4.4; Complex!double[] z; z.length=N; z[] = complex(x[],y[]); // z = complex(x,y); // also tried this, did not work } - The compile error message is: rdmd post.d post.d(22): Error: template `std.complex.complex` cannot deduce function from argument types `!()(double[], double[])`, candidates are: /home/leblanc/dmd2/linux/bin64/../../src/phobos/std/complex.d(46):`complex(R)(const R re)` /home/leblanc/dmd2/linux/bin64/../../src/phobos/std/complex.d(56):`complex(R, I)(const R re, const I im)` with `R = double[], I = double[]` whose parameters have the following constraints: `` ` > is(R : double) - is(I : double) ` `` post.d(22):All possible candidates are marked as `deprecated` or `@disable` Tip: not satisfied constraints are marked with `>` Failed: ["/home/leblanc/dmd2/linux/bin64/dmd", "-v", "-o-", "post.d", "-I."] --- I understand, I could write a simple function to do this...but was wondering if there is some "standard" way of doing this already? Thanks, James PS Is cdouble (and friends) really going to be deprecated?? I worry that the loss of the built-in complex types eventually might have a downside for syntax and writing. (But, I might very well be wrong about this!!).
Re: betterC shared static ctor
On Wednesday, 21 July 2021 at 08:11:06 UTC, vit wrote: Is it possible to call all shared static ctors in betterC? ```d //-betterC static immutable int i; shared static this(){ i = 42; } extern(C) void main(){ assert(i != 42); } ``` These rely on DRuntime, which is not linked in betterC mode. You'll need to use the `crt_constructor` and `crt_destructor` pragmas: https://dlang.org/spec/pragma.html#crtctor Apply them to any `extern(C) function for static ctor/dtor behavior.
betterC shared static ctor
Is it possible to call all shared static ctors in betterC? ```d //-betterC static immutable int i; shared static this(){ i = 42; } extern(C) void main(){ assert(i != 42); } ```
Re: Can static variables in methods be local for each object?
On Tuesday, 20 July 2021 at 15:59:30 UTC, Dukc wrote: On Tuesday, 20 July 2021 at 09:24:07 UTC, Mark Lagodych wrote: Is there a way to make myvar local to each instance of `X` without making it a variable of `X`? Just curious. Yes. ```d import std.stdio; class X { int x(int param) { static int[typeof(this)] myvar; if (param == 0) return myvar.get(this, 1234); else return myvar[this] = param; } } void main() { X x1 = new X; X x2 = new X; x1.x(0).writeln; //1234 x2.x(0).writeln; //1234 x1.x(17).writeln; //17 x2.x(0).writeln; //1234 x1.x(0).writeln; //17 x2.x(0).writeln; //1234 } ``` However, this is definitely not recommended. When you are calling a function with any particular object and argument set, you want it to do the same thing and return the same result, regardless of what's called before. Otherwise you're making debugging much more difficult than it needs to be. This means that `static` variables should generally be used only for two things: 1: data that is only set at the beginning of the program, or at first use, and then left to the initial value. 2: caching results of expensive computation. Even this is a bit controversal, as it's easy to screw up - often it's just better to split the function in two, and let the caller to cache the results. In this case, consider passing `myvar` explicitly: ```d import std.stdio; class X { int x(int param, ref int[typeof(this)] myvar) { if (param == 0) return myvar.get(this, 1234); else return myvar[this] = param; } } void main() { X x1 = new X; X x2 = new X; int[X] myvar; x1.x(17, myvar).writeln; //17 x2.x(0, myvar).writeln; //1234 x1.x(0, myvar).writeln; //17 x2.x(0, myvar).writeln; //1234 myvar = null; //Forget all calls made so far x1.x(0, myvar).writeln; //1234 x2.x(0, myvar).writeln; //1234 } ``` Wait, that's not too shabby to use the this pointer for a key to an AA. It isn't really a single static variable however, but rather an AA that contains the static variables.
Re: How to parse a json node that contains children of different types?
On Wednesday, 21 July 2021 at 03:00:51 UTC, Mathias LANG wrote: TL;DR: If you want to use loosely typed data in a strongly typed language, you need to come up with a common type. That common type is usually either a discriminated union (which a JSON object is, essentially) or something that is domain-specific. Hope this helps. I had a quick look at asdf and couldn't see a support for tagged union, so you would probably need to provide your data structure with a `deserializeFromAsdf` method. If you want to do so, look into providing a wrapper to `SumType`, e.g.: ``` struct MyUnion (T...) { SumType!T data; alias data this; SerdeException deserializeFromAsdf(Asdf data) { /* Fill in the SumType */ } ``` But I would recommend just using the JSON object if you can. Thank you! From your answer, I realized that in fact, I would rather do the parsing of these arguments myself. Before using asdf, I tried to do the same with the standard std.json. The problem is the same there. I agree that this is logical for D. I was also interested in SumType, I will try to do something with it for experience.