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.
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: 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 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 ?
Re: Not allowed to globally overload operators?
On Tuesday, 20 July 2021 at 18:32:26 UTC, Ali Çehreli wrote: On 7/19/21 11:20 PM, Tejas wrote: > trying to create the spaceship operator of C++ Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics. Ali I know. As I already mentioned, I just wanted the ```<=>``` symbol :(
How to Fix Weird Build Failure with "-release" but OK with "-debug"?
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
Re: How to parse a json node that contains children of different types?
On Tuesday, 20 July 2021 at 21:18:12 UTC, Bagomot wrote: But there is a problem with different types. I understand that Object[] is not suitable here, but I don’t know how to do it. I ask you to help me with this. IIUC, the `arguments` are command line arguments passed to a Java program, and some of those might be passed to the JVM ? So you probably will end up with something like: ``` struct Arguments{ JVMArgs jvm; ProgramArgs program; } ``` Of course, the question is, what's `JVMArgs` ? Now, as you noticed, you can't represent an array of unrelated types in D (which makes sense). So what you can do is create a common type for it, by using an `union`. ``` union JVMArg { RuleValue ruleValue; string str; // Etc... } alias JVMArgs = JVMArg[]; ``` However, \ might not support it directly, or might support it through its own type (you will need a tagged union, and not just a simple union, as you need to know the type that the library read). 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. Instead, I would recommend to just use the JSON directly. If you need to pass things around, you might want to deserialize it to a common format. For example, assuming your project is a process manager for Java program and you want to read a common set of arguments from a configuration file, you might want to just generate the strings: ``` auto myJSON = parseConfigFile("config.json"); string[] defaultJVMArgs = parseJVMArgs(myJSON); auto processMonitor = new ProcessMonitor(defaultJVMArgs); ``` 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.
How to parse a json node that contains children of different types?
I have a json like this: ```json { "arguments":{ "jvm":[ { "rules":[ { "action":"allow", "os":{ "name":"osx" } } ], "value":[ "-XstartOnFirstThread" ] }, "-Djava.library.path=${natives_directory}" ] } } ``` Here the "jvm" node is an array that has different data types for its elements (json object and string). I am using [asdf](https://code.dlang.org/packages/asdf) library to deserialize json. I am trying to deserialize this json into a structure like this: ```d struct Arguments{ @serdeKeys("jvm") Object[] jvm; } ``` But there is a problem with different types. I understand that Object[] is not suitable here, but I don’t know how to do it. I ask you to help me with this.
Re: Not allowed to globally overload operators?
On 7/20/21 11:49 AM, H. S. Teoh wrote: > On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: >> On 7/19/21 11:20 PM, Tejas wrote: >> >>> trying to create the spaceship operator of C++ >> >> Just to make sure, D's opCmp returns an int. That new C++ operator was >> added to provide the same semantics. > [...] > > FYI, opCmp *may* return float, which may be useful sometimes for > implementing partial orders (return float.nan when two elements are > incomparable). Thanks. For that matter, opCmp can return a UDT (and bool as well as demonstarted below) but then the UDT cannot know what to do in its opCmp: :) import std.stdio; void main() { S a, b; auto result = a < b; // The operator above is reduced to the following: // // a.opCmp(b) < 0; // // (It would be 'a.opCmp(b) >= 0' if we used the >= operator, etc.) // // But because the result of opCmp is an O object in this code // (let's call it 'o'), the reduction is applied to 'o < 0' as well: // // o.opCmp(0); // // where, O.opCmp will receive a 0 'int' value but will never know // operator context we are in. (<, >=, etc.) } struct S { // Weirdly returns an O. O opCmp(const S that) { return O(); } } struct O { bool opCmp(int result) { // result will always be '0' in the case of reduction because it // will be the 0 used in code reduction by dmd. // We might be able to do something here but we don't know the // operator context. Are we inside <, >=, etc? // Extra credit: This is similar to being able to return float.nan // but I can't decipher the semantics at this time. :) return true; } } Ali
Re: Not allowed to globally overload operators?
On Tuesday, 20 July 2021 at 18:49:07 UTC, H. S. Teoh wrote: On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: On 7/19/21 11:20 PM, Tejas wrote: > trying to create the spaceship operator of C++ Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics. [...] FYI, opCmp *may* return float, which may be useful sometimes for implementing partial orders (return float.nan when two elements are incomparable). To be precise about it: `opCmp` must return a value that can be compared with `0` using `<` and `>`. Any integer or floating-point type will satisfy this requirement.
Re: Not allowed to globally overload operators?
On Tue, Jul 20, 2021 at 11:32:26AM -0700, Ali Çehreli via Digitalmars-d-learn wrote: > On 7/19/21 11:20 PM, Tejas wrote: > > > trying to create the spaceship operator of C++ > > Just to make sure, D's opCmp returns an int. That new C++ operator was > added to provide the same semantics. [...] FYI, opCmp *may* return float, which may be useful sometimes for implementing partial orders (return float.nan when two elements are incomparable). T -- "Outlook not so good." That magic 8-ball knows everything! I'll ask about Exchange Server next. -- (Stolen from the net)
Re: Not allowed to globally overload operators?
On 7/19/21 11:20 PM, Tejas wrote: > trying to create the spaceship operator of C++ Just to make sure, D's opCmp returns an int. That new C++ operator was added to provide the same semantics. Ali
Re: Can static variables in methods be local for each object?
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 } ```
Re: Can static variables in methods be local for each object?
On Tuesday, 20 July 2021 at 09:24:07 UTC, Mark Lagodych wrote: Let's say I have this code: ```d import std.stdio; class X { int x(int param) { static int myvar = 1234; if (param == 0) return myvar; else { myvar = param; return myvar; } } } void main() { X x1 = new X; X x2 = new X; x1.x(0).writeln; x2.x(0).writeln; x1.x(17).writeln; x2.x(0).writeln; } ``` Is there a way to make myvar local to each instance of `X` without making it a variable of `X`? Just curious. The only way I can think of is something like this: ``` import std.stdio; interface X { int x(int param); } class XImpl(size_t n = 0) : X { int x(int param) { static int myvar = 1234; if (param == 0) return myvar; else { myvar = param; return myvar; } } } void main() { X x1 = new XImpl!1; X x2 = new XImpl!2; x1.x(0).writeln; x2.x(0).writeln; x1.x(17).writeln; x2.x(0).writeln; } ``` Of course it's not entirely what you want but yeah I think that's about the closest to a solution that isn't overcomplicated.
Re: Can static variables in methods be local for each object?
On Tuesday, 20 July 2021 at 09:24:07 UTC, Mark Lagodych wrote: ```d void main() { X x1 = new X; X x2 = new X; x1.x(0).writeln; x2.x(0).writeln; x1.x(17).writeln; x2.x(0).writeln; } ``` Ow, sorry, I forgot to say. It prints: ``` 1234 1234 17 17 ```
Can static variables in methods be local for each object?
Let's say I have this code: ```d import std.stdio; class X { int x(int param) { static int myvar = 1234; if (param == 0) return myvar; else { myvar = param; return myvar; } } } void main() { X x1 = new X; X x2 = new X; x1.x(0).writeln; x2.x(0).writeln; x1.x(17).writeln; x2.x(0).writeln; } ``` Is there a way to make myvar local to each instance of `X` without making it a variable of `X`? Just curious.