July 18, 2022

On Monday, 18 July 2022 at 17:20:04 UTC, Kagamin wrote:

>

Difference between null and empty is useless.

Not really. null typically means that the value is missing, irrelevant and not usable, which is quite different from having "" as a usable value.

July 18, 2022

On Monday, 18 July 2022 at 17:20:04 UTC, Kagamin wrote:

>

... If you want such difference, use the Nullable wrapper or Algebraic.

I do :-) In fact, I use algebraic types supporting Null and Undefined for DTOs representation (and REST APIs). But I discovered some "rare" side effects in libraries like vibe.d and structs where, sometimes, am empty string is deserialized as null (value is null) and I have to assume that null in an string is always "" for avoiding this weird effects

I'm under pressure to meet deadlines and a team that is telling me "Why D instead typescript, Antonio?"... One month ago I reported some questions in forums or git repos... but I have to finish my work and 2 hours stoppers are not acceptable now.

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.

July 19, 2022

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.

July 19, 2022

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:

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);

July 19, 2022

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).

July 19, 2022
>> 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 ...
July 19, 2022

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).

July 19, 2022

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:

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.

July 19, 2022

Also what's the difference between null and empty phone number?

July 19, 2022

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<City> 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:

person.ns.address.ns.city.ns.name.match!(
  (string name){ ... }
  (Null) {...}
  (Undefined) { ... }
)