Hacker News new | past | comments | ask | show | jobs | submit login

I am sure they are very good reasons for it, but even after reading part of the latest valhala design document i still don't quite understand by nullability and/or identity are used as key differential between value types and "regular" class type. It seems to make the design and integration of value object very convoluted and is basically representational flatness as a mere consequences instead of being the central defining factor of a value object.



> basically representational flatness as a mere consequences

And that’s exactly what they are going for, AFAIK.

You as a programmer should first and foremost care about the semantics that you want to express in your programs. In many cases it means that an object you use has and need an identity. But you may find so that it doesn’t make sense in a given case, like a date, or a coordinate — so you can express that it doesn’t have identity, allowing for more freedom on the compilers part.

Finally, you may even say that an implicitly zeroed object makes sense as a default for your class, and when this particular case happens and your object can’t be null, the compiler can even completely inline/flatten your data. But the performance improvements are generally not the goal themselves, they are neat advantages you may get by restricting your semantics.


> You as a programmer should first and foremost care about the semantics that you want to express in your programs.

I think what is semantics vs implementation details depends on the task at hands. From my understanding, the need for value types mainly originate from the need for precise control of memory layout, In which case the representation is part of the important semantic. C#/.Net seems to have a simpler approach by just providing representation flatness as a tool and let the developer chose what they want to do/focus on.

> In many cases it means that an object you use has and need an identity. But you may find so that it doesn’t make sense in a given case, like a date, or a coordinate — so you can express that it doesn’t have identity, allowing for more freedom on the compilers part.

If this is confusing it to me, the need to identity seems to be a property of a specific object instance, not really a property of a class/type.

> But the performance improvements are generally not the goal themselves

I am not sure how true this is, the design document itself reference numeral code performance as one of motivating factor.

> when this particular case happens and your object can’t be null, the compiler can even completely inline/flatten your data

As someone who have "worked" on quite of bit of runtime/compilers, "compiler can" always turns out to be "compiler doesn't". This idea of a compiler to auto-magically deciding and optimizing data layout sound great in theory, but in practice is very very hard to achieve in most meaningful ways.


C# and Java have very different philosophies here - the former prefers exposing the primitives to the developers at the price of a simpler runtime but a more complex language, while java does the opposite.

Of course performance is a goal, but they asked the fundamental questions around the topic, and managed to boil it down to something that will also solve another painpoint of the language at the same time, and help heal the rift between primitives and objects.

And your last paragraph is true in general, but the explicit goal of all this is to restrict the possible semantics of code to enable optimizations - so in the end a compiler-enforced nullable, primitive class will be reliably flattened.


> C# and Java have very different philosophies here - the former prefers exposing the primitives to the developers at the price of a simpler runtime but a more complex language, while java does the opposite.

I don't think it fair to say that the addition of struct in C# make it a more complex language. If anything ( well i might be bias here, since i am mainly a C++/native dev.) it make it explicit the difference between reference semantic and value semantic in a way that is very easily identifiable.

> solve another pain point of the language at the same time, and help heal the rift between primitives and objects.

From my perspective , this is root cause of the issue. A "primitive value" and an object (in the java/small talk tradition) are not the same category of thing and do not belong on the same hierarchy. It seems to me that somewhere in mid early to mid 2000, java/jvm looked at C++ and wanted to have unified type hierarchy or somehow treat values and object as the same thing. This is only possible in C++ and other native languages because those do not have "object" as defined in small talk.

The main issue with the primitive and object being different were that one can't defined additional primitive types with more complex behavior and that the generic system doesn't work well with primitive types. And now instead of addressing those two simple problems effectively, we have project valhala which took more than a decade to arrive to solution that looks to me less elegant.

Sometime two simple solution are better than one big abstract design.


Structs may not be a big and complex addition to a language, but C# has done something like this for many times, and I would definitely rank the language somewhere below c++ in complexity. Swift is another similarly complex language with very non-trivial interactions between said features.

> And now instead of addressing those two simple problems effectively

Those are not all simple problems.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: