Re: Expanding CTFE code during compilation
On 7/19/22 8:57 PM, Steven Schveighoffer wrote: There's a slight bloat in the compiler symbol table when but other than that it should be effective. Obviously I didn't finish that thought... "when `-debug` isn't used on the command line" -Steve
Re: Expanding CTFE code during compilation
On 7/19/22 8:33 PM, Azi Hassan wrote: Nice, a compile time console.log. Thanks a lot, this will come in handy. I wonder if it can be combined with version(debug) to only run the pragma line if compiled with -g, this way we can keep the printEnum! line as it is. Then again, the code would become polluted by debugging logic Yep: ```d debug template printEnum(...) { ... // everything we already did } else enum printEnum(alias x) = x; ``` There's a slight bloat in the compiler symbol table when but other than that it should be effective. -Steve
Re: Expanding CTFE code during compilation
On Tuesday, 19 July 2022 at 22:41:43 UTC, Steven Schveighoffer wrote: On 7/19/22 5:43 PM, Azi Hassan wrote: Just in case this is a consequence of the XY problem, the reason why I'm looking for this is to make sure that the code I wrote did evaluate to what I'm expecting it to. Right now I do this with an enum assignment followed by static asserts, but I'd love it for there to be some sort of visual feedback. Thanks in advance ```d template printEnum(alias x, string file = __FILE__, size_t line = __LINE__) { enum printEnum = x; pragma(msg, file, "(", int(line), "): ", printEnum); } enum x = printEnum!(iota(1, 5).reduce!"a * b"); ``` This will spit out the file, line, and value for the declaration. Assuming this is useful for your double-checking you could do this, and then switch it back when you have verified that it's correct. -Steve Nice, a compile time console.log. Thanks a lot, this will come in handy. I wonder if it can be combined with version(debug) to only run the pragma line if compiled with -g, this way we can keep the printEnum! line as it is. Then again, the code would become polluted by debugging logic
Re: Expanding CTFE code during compilation
On Tuesday, 19 July 2022 at 22:27:56 UTC, Dennis wrote: On Tuesday, 19 July 2022 at 21:43:01 UTC, Azi Hassan wrote: I'm wondering if the offers has the option of executing the parts that can be evaluated at compile time and then replacing them with the result of this evaluation. Try the `-vcg-ast` flag: ```D import object; import std; void main() { enum int x = 24; writeln(24); return 0; } // ... and a bunch of template instances ``` Thanks a lot, this is exactly what I had in mind. Where did you find it though ? I checked dmd --help and man dmd before making this thread, but to no avail.
Re: Choosing the correct compiler version
On Tuesday, 19 July 2022 at 15:33:59 UTC, Alexander Zhirov wrote: On Tuesday, 19 July 2022 at 15:28:44 UTC, Alexander Zhirov wrote: I'm trying to install dmd with my hands in order to build ldc2 from the sources, but I can't: I need to build a compiler under x32 in order to compile a program for the same machine. ```sh dmd2/src/dmd# make -f posix.mak posix.mak:42: = DEPRECATION NOTICE = posix.mak:43: = DEPRECATION: posix.mak is deprecated. Please use src/build.d instead. posix.mak:44: == dmd -of../generated/build -g build.d dmd: /lib/libc.so.6: version `GLIBC_2.28' not found (required by dmd) posix.mak:111: recipe for target '../generated/build' failed make: *** [../generated/build] Error 1 ``` You can find the release archive linked from https://dlang.org/download.html , after clicking 'Download' by dmd. It's at http://downloads.dlang.org/ You can then go through old versions and, by trial, find one that's old enough to work on your machine, which you can then use to a newer dmd: for x in dmd druntime phobos; do git clone https://github.com/dlang/$x; done export HOST_DMD=path/to/bin32/dmd ( cd dmd; make -f posix.mak ) # etc. Finding an old version that works on your machine will be very easy, but for example the random 2016 build that I grabbed was also too old to build dmd master, so you want to prefer a newer build that still works. It's not necessary to build dmd master though: in the worst case, you should be able check out interim releases (look at 'git tag --list', then 'git checkout v2.094.0' for example), build those, then used them to build a newer release. This is all of course a massive PITA, which any extremely nice person could make less of a pain by cataloguing useful versions on the D wiki or by providing their own "good enough to compile master" builds for old architectures. Another option is to get newer glibc onto this system (not installing it, just making it available for dmd. use LD_LIBRARY_PATH). An option that's technically possible but probably even more of a pain than what I've just described is using another machine to cross-compile static 32-bit D binaries that will then work on this machine. I've tried this and run into pretty unpleasant limitations, but I have a guide anyway at https://d.minimaltype.com/index.cgi/wiki?name=statically-linked+binaries , which you can supplement with https://wiki.dlang.org/Cross-compiling_with_LDC to get a 32-bit result. For that matter 'ldc2 -mtriple i686-linux-musl file.d' might be made to work, but I've no idea how to supply the toolchains that it expects. Speaking of toolchains, it might be possible to use a modern server with a modern dmd with an ancient glibc: https://www.lordaro.co.uk/posts/2018-08-26-compiling-glibc.html
Re: Expanding CTFE code during compilation
On 7/19/22 5:43 PM, Azi Hassan wrote: Just in case this is a consequence of the XY problem, the reason why I'm looking for this is to make sure that the code I wrote did evaluate to what I'm expecting it to. Right now I do this with an enum assignment followed by static asserts, but I'd love it for there to be some sort of visual feedback. Thanks in advance ```d template printEnum(alias x, string file = __FILE__, size_t line = __LINE__) { enum printEnum = x; pragma(msg, file, "(", int(line), "): ", printEnum); } enum x = printEnum!(iota(1, 5).reduce!"a * b"); ``` This will spit out the file, line, and value for the declaration. Assuming this is useful for your double-checking you could do this, and then switch it back when you have verified that it's correct. -Steve
Re: Expanding CTFE code during compilation
On Tuesday, 19 July 2022 at 21:43:01 UTC, Azi Hassan wrote: I'm wondering if the offers has the option of executing the parts that can be evaluated at compile time and then replacing them with the result of this evaluation. Try the `-vcg-ast` flag: ```D import object; import std; void main() { enum int x = 24; writeln(24); return 0; } // ... and a bunch of template instances ```
Expanding CTFE code during compilation
Hello, Apologies in advance if this has been asked before. I can't find the right words to express what I'm looking for, but essentially, I'm wondering if the offers has the option of executing the parts that can be evaluated at compile time and then replacing them with the result of this evaluation. The C equivalent would be compiling with the -E flag as explained here : https://stackoverflow.com/questions/4900870/can-gcc-output-c-code-after-preprocessing For example : ``` //main.d import std; void main() { enum x = iota(1, 5).reduce!"a * b"; x.writeln(); } ``` Then after running something like ``` dmd --expand-ctfe main.d -o expanded.d cat expanded.d ``` We'd get : ``` //expanded.d import std; void main() { 24.writeln(); } ``` Just in case this is a consequence of the XY problem, the reason why I'm looking for this is to make sure that the code I wrote did evaluate to what I'm expecting it to. Right now I do this with an enum assignment followed by static asserts, but I'd love it for there to be some sort of visual feedback. Thanks in advance
Re: null == "" is true?
On Tuesday, 19 July 2022 at 17:05:27 UTC, Kagamin wrote: Also what's the difference between null and empty phone number? In a relational database, `NULL` is not the same that `""`... and `NULL` is not the same that `0`. Are semantically different and there are database invariants (like foreign keys) based on it. Trying to "mix" this concepts in a database is a mistake. When you treat with Domain Models, you try to represent this semantics in all levels of your software... including APIs If your address has not a reference to the city... then there is a `city_code` field with `NULL` value in your database and the Address model object has a city property representing this Null value with the tools that language/library offers to you: `Nullable!City` or `Sumtype!(Null, City)` or `Optional` or ...). `Null` is then a valid value state that has nothing related to *`null` pointers*... to avoid confusion, I talk about `Null` instead `null`. I, personally, prefer to use Union types (algebraic types) like `int | Null | ...` because it is the best option to introduce the Undefined state (that allows statically typed data to represent the absence of a property). `Sumtype!(Undefined,Null,int)` instead `Optional!(Nullable!int)` Then there is the `match!` syntax, the unified way to treat JSON serialization and the easy way to implement a custom "dot" accessor that propagates the Null or Undefined state in a chain of references: ```d person.ns.address.ns.city.ns.name.match!( (string name){ ... } (Null) {...} (Undefined) { ... } ) ```
Re: null == "" is true?
Also what's the difference between null and empty phone number?
Re: null == "" is true?
On Tuesday, 19 July 2022 at 10:29:40 UTC, Antonio wrote: The summary is that a DTO that works like a Map needs to represent the absent key ant this is not the same that the Null value Example: ```d struct Null { /*...*/ } struct Undefined { /*...*/ } struct ContactDto { DtoVal!(Undefined, string) name DtoVal!(Undefined, Null, string) phonenumber, DtoVal!(Undefined, AddressDto) address } // ... ContactDto data = {phonenumber:Null(), address:{city:{code:"BCN"}}}; updateContact(id, data); ``` As I understand, in your scenario there's no difference between null string and empty string, they both work like empty string, and D treats them as empty string. That's what I mean when I said that distinction between null and empty is meaningless.
Re: null == "" is true?
On Tuesday, 19 July 2022 at 15:30:30 UTC, Bienlein wrote: If the destination of a carrier was set to null, it implied that the destination was currently undefined. Then the robot brought the carrier to some rack where it was put aside for a while till the planning system had created a new production plan. The number of null pointer exceptions we had to fix because auf this was countless. Never make null imply some meaning ... This is due to a lack of proper abstractions. Null always has a meaning, if it didn't, you would not need it. In this particular case you could have used a singleton instead. In a relational database you can choose between having null or having a large number of tables. The latter performs poorly. I am not talking about how to implement null, I am talking about the concept of information being absent. If you have to represent that, you have a defacto "null", doesn't matter if it is a singleton or address zero or NaN or FFFE (for unicode).
Re: Choosing the correct compiler version
On Tuesday, 19 July 2022 at 15:28:44 UTC, Alexander Zhirov wrote: I'm trying to install dmd with my hands in order to build ldc2 from the sources, but I can't: I need to build a compiler under x32 in order to compile a program for the same machine. ```sh dmd2/src/dmd# make -f posix.mak posix.mak:42: = DEPRECATION NOTICE = posix.mak:43: = DEPRECATION: posix.mak is deprecated. Please use src/build.d instead. posix.mak:44: == dmd -of../generated/build -g build.d dmd: /lib/libc.so.6: version `GLIBC_2.28' not found (required by dmd) posix.mak:111: recipe for target '../generated/build' failed make: *** [../generated/build] Error 1 ```
Re: null == "" is true?
why? Because an empty string is, by default, represented by an empty slice of the null pointer. I don't program in D. I just read from time to time posts in the D forum because of the good quality of what people write. So, I'm not proficient in D, but in general internals should not boil up to the surface. In my experience null and empty in DTOs usually play the same logical role. Oh, oh ... IIRC someone wrote a master thesis about the different roles for null values in databases >and came up with many different null situations (was it five?). Oh, oh, oh ... I once worked on a system where some little robot running on a track picked up material in carriers from some machine and then brought it to the next machine. If the destination of a carrier was set to null, it implied that the destination was currently undefined. Then the robot brought the carrier to some rack where it was put aside for a while till the planning system had created a new production plan. The number of null pointer exceptions we had to fix because auf this was countless. Never make null imply some meaning ...
Choosing the correct compiler version
Hello everyone I want to install the `ldc2` compiler on a specific machine `i586`: ```sh ~ $ strings /lib/libc.so.6 | grep GLIBC GLIBC_2.0 GLIBC_2.1 GLIBC_2.1.1 GLIBC_2.1.2 GLIBC_2.1.3 GLIBC_2.2 GLIBC_2.2.1 GLIBC_2.2.2 GLIBC_2.2.3 GLIBC_2.2.4 GLIBC_2.2.6 GLIBC_2.3 GLIBC_2.3.2 GLIBC_2.3.3 GLIBC_2.3.4 GLIBC_2.4 GLIBC_2.5 GLIBC_2.6 GLIBC_2.7 GLIBC_2.8 GLIBC_2.9 GLIBC_2.10 GLIBC_2.11 GLIBC_2.12 GLIBC_2.13 GLIBC_2.14 GLIBC_2.15 GLIBC_2.16 GLIBC_2.17 GLIBC_2.18 GLIBC_2.22 GLIBC_2.23 GLIBC_PRIVATE ``` I'm trying to install dmd with my hands in order to build ldc2 from the sources, but I can't: ```sh ~ $ dmd --version dmd: /lib/libc.so.6: version `GLIBC_2.28' not found (required by dmd) ``` Please tell me which version for the current configuration I can use?
Re: null == "" is true?
On Tuesday, 19 July 2022 at 10:29:40 UTC, Antonio wrote: NULL is not the same that UNDEFINED The distintion is really important: NULL is a valid value (i.e.: The person phonenumber is NULL in database)... Of course, you can represent this concept natively in you language (Nullable, Optional, Maybe ...) but it is not the same that UNDEFINED... because UNDFINED says "This property has not been assigned to DTO... do not take it into account". IIRC someone wrote a master thesis about the different roles for null values in databases and came up with many different null situations (was it five?). E.g. for floating point you have two different types of not-a-number, one for representing a conversion failure/corruption of a datafield and another one for representing a computational result that cannot be represented. If we consider zero to be "empty" then floating point has four different "empty" values (+0, -0, qNaN, sNaN).
Re: null == "" is true?
On Tuesday, 19 July 2022 at 08:10:25 UTC, Kagamin wrote: On Monday, 18 July 2022 at 21:23:32 UTC, Antonio wrote: I will study it in detail and report (if required). May be, I will write the DTO problem with D article if I find time in august. In my experience null and empty in DTOs usually play the same logical role. It's a very contrived technical difference without practical usage, such distinction is way beyond any business logic. Even if you implement this distinction, I'm not sure anybody will carefully pay attention to it. In languages that make difference between null and empty, null is often replaced with empty to work around problems with null, such codebase can't properly preserve null values. When you have to "patch" information partially (i.e.: update only the name and the phonenumber, but not the birthdate) or you must return in a REST partial information (because graphql or custom REST) there is only 2 ways to represent this "possible missing properties" * Maps (key->value) or similiar (i.e.:JSon objects): You can include or not keys in the map: If you don't want to update the birthdate, don't include the birthdate key in the DTO. * Structs (or any kind of structured data that can be validated at compile time): There is no possibility to say that some properties of the struct can be not present... Well, you can if you begin to manage Algebraic Types (Union types): `height: int | undefined` NULL is not the same that UNDEFINED The distintion is really important: NULL is a valid value (i.e.: The person phonenumber is NULL in database)... Of course, you can represent this concept natively in you language (Nullable, Optional, Maybe ...) but it is not the same that UNDEFINED... because UNDFINED says "This property has not been assigned to DTO... do not take it into account". The summary is that a DTO that works like a Map needs to represent the absent key ant this is not the same that the Null value Example: ```d struct Null { /*...*/ } struct Undefined { /*...*/ } struct ContactDto { DtoVal!(Undefined, string) name DtoVal!(Undefined, Null, string) phonenumber, DtoVal!(Undefined, AddressDto) address } // ... ContactDto data = {phonenumber:Null(), address:{city:{code:"BCN"}}}; updateContact(id, data); ```
Re: null == "" is true?
On Monday, 18 July 2022 at 21:23:32 UTC, Antonio wrote: I will study it in detail and report (if required). May be, I will write the DTO problem with D article if I find time in august. In my experience null and empty in DTOs usually play the same logical role. It's a very contrived technical difference without practical usage, such distinction is way beyond any business logic. Even if you implement this distinction, I'm not sure anybody will carefully pay attention to it. In languages that make difference between null and empty, null is often replaced with empty to work around problems with null, such codebase can't properly preserve null values.