> C# doesn't do escape analysis and automatically put things on the stack
There has been work ongoing in this direction since .NET 9 at least, but the effect is very limited currently. The following code however, has no allocations at runtime, despite having an object creation in the code:
> When you have an expression P which names a mutable place, and you execute P := X
This isn't the case, though, is it? A normal member access (or indexer) expression may point to a mutable location (field, property). However, with conditional access expressions you get either a member access _or nothing_. And that nothing is not a mutable place.
When you use any of the conditional operators, you split the following code into two paths, and dropping the assignment (since there's nothing to assign to) seems pretty consistent to me, since you'd also drop an invocation, or a property evaluation in similar expressions.
If you require P to point to something that actually exists because you want the assignment to succeed, then write code to ensure that P exists because the assignment has no way of knowing what the intention was on the left side.
If the language allows <whatever> := <new-value> --- if that compiles and executes --- then <whatever> is by definition a mutable place.
Once you introduce this misfeature, mutable places no longer have the property that they all record the assigned value and keep it until the next assignment.
Now, sure, you also don't have that property when you have operator overloading that allows assignment to be coded by the programmer; but that's a design decision under the programmer's control which affects only that code base, not the entire language and all its users.
I think in the context of C# this is not exactly unexpected since there are various operators that apply conditional execution (and evaluation) to parts of an expression. All of them start with ?, though (? :, ??, ?., ?[], ??=), so except for casts to nullable types, every question mark in an expression signals that control flow is about to happen and it's been that way in C# for quite a while.
[Too late, sorry for the delay, but I had to think about it.]
That ooks like a good reason. Looking at https://learn.microsoft.com/en-us/dotnet/csharp/language-ref... , the magic is in the LHS or the RHS, and in ??= the magic is explicitly in the connection. Here, IMHO, the problem is that the magic jumps from one side to the other. Anyway, I don't use C#.
I stumbled over this a few times, mostly when cleaning up older code. This basically just means that using the ?. member access no longer dictates what is possible on the right side.
Property reads were fine before (returning null if a part of the chain was null), method invocations were fine (either returning null or just being a no-op if a part of the chain was null). But assignments were not, despite syntactically every ?. being basically an if statement, preventing the right side from executing if the left side is null (yes, that includes side-effects from nested expressions, like arguments to invocations).
So this is not exactly a new feature, it just removes a gotcha from an old one and ensures we can use ?. in more places where it previously may have been useful, but could not be used legally due to syntax reasons.
> The goal for Valhalla is value types, reified generics if they ever happen is still open.
But if they want the List<int> use case to be fast they basically have to keep this information at runtime and will have to make changes to how objects are laid out in memory. I'm not sure there's a good way around that if you want List<int> to be backed by an int[] and `get` returning an int instead of an Object. This may or may not be available to developers and remain internal to the JVM in the beginning, but I think it's necessary to enable the desired performance gains.
They also state on the website: »Supplementary changes to Java’s generics will carry these performance gains into generic APIs.«
Haskell and OCaml are two runtimes that do just good enough with type erasure for how the polymorphic types get implemented across their implementations.
Probably MLton is the only implementation that actually does it the C++ and Rust way.
So lets see how far they go.
I always considered it was a mistake for Java to ignore what GC enabled languages were doing at the time, Eiffel, Modula-3, Oberon and frieds, which they naturally looked into given their influences, but it wasn't deemed necessary for the original Java purposes of being a settop box and applets language.
Now we have a good case of what happens when we tried to retrofit such critical features after decades of field usage, a lesson that Go folks apparently failed to learn as well.
Help on either project actually flows both ways. If I remember correctly, Wendelstein 7-X provided experience and know-how regarding microwave heating and welding large plasma vessels. In the end they're scientists and engineers and don't seem to see the other project so much as competition than a way to learn more than just with one of them.
Browsers typically say below the styles also which fonts are actually used (there can be multiple, e.g. when substitution is required to render certain characters).
There has been work ongoing in this direction since .NET 9 at least, but the effect is very limited currently. The following code however, has no allocations at runtime, despite having an object creation in the code:
https://sharplab.io/#v2:C4LghgzgtgPgAgJgIwFgBQcDMACR2DC2A3ut...
reply