Coder Social home page Coder Social logo

Comments (5)

lrhn avatar lrhn commented on September 23, 2024

Yeah, it's two different ways to say the same thing: that any two integer values that are equal, are also identical.

That's the whole truth. We don't actually say whether two integer object references with the same numerical value is the same instance or not, or whether identical just checks equality instead of object identity for integers.
That's an implementation detail.

The second comment should probably say "a new reference to a number that etc."

from language.

Cat-sushi avatar Cat-sushi commented on September 23, 2024

First of all, I feel I understand implementation detail, and the problem is just ways to say.

The second comment should probably say "a new reference to a number that etc."

I don't think so.
I bereave two different reference which points the same object are identical.

from language.

Cat-sushi avatar Cat-sushi commented on September 23, 2024

My understanding is that,

  • All dart types are reference types.
  • At the same time, int, double, bool, String, Null and Record are value types.
  • int, double, bool, String and Null are all immutable and canonicalized, so we can't notify whether two "identical" variables have the same reference value or just same object values referred.
  • Expando have some restriction for some implementation reasons, but not for semantical reasons.

from language.

lrhn avatar lrhn commented on September 23, 2024
  • All dart types are reference types.

Probably at least technically correct. At least except records.

  • At the same time, int, double, bool, String, Null and Record are value types.

Yeah, it's like a wave/particle duality. And each type has its own different subtle details.
And it hinges on what it means to be a reference type, and what a reference is to begin with.

The usual definitions are:

  • Reference types are types where the data is not stored directly in variables, but a reference to the data is.
  • So assigning from one variable to another doesn't copy the data, it just copies the reference.
  • The references in Dart point to objects.
  • Objects (in traditional Object Orientation) have persistent identity. They are entities.
  • Identity is a unique property of each object.
  • Which is why we can answer whether two references are references to the same object, if the objects they point to have the same identity.
  • A value type is usually not a reference type, may be copied when assigned, and may not have a persistent identity (but it can, which is why we can tell that the assignment created a new copy).

That means that if something is a reference object type, then var y = ...; var x = y; print(identical(x, y)); should always print true. The assignment does not create a new object, it points to the same object, which has persistent identity, which identical can check.

For mutable objects, creating a copy is a big deal. It means changes to the original won't show in the copy.
For immutable objects, it's less visible. The only distinction is whether identical says it's the same identity afterwards.

And for immutable objects, it's impossible to tell the difference between an identical which lies, and just checks == after copying, and values which are auto-canonicalized on creation and do have persistent identity.

With that:

  • String is generally a plain object. On native it really is just normal objects, on the web it's auto-canonicalized (really: identical lies).
  • int and double are always auto-canonicalized (aka. identical lies).
  • bool and Null are more like enums with language literals to get the values. Nothing special about them otherwise, just plain objects.
  • Records are ... special. They are reference types, but do not (necessarily) have persistent identity. Which means that they may not only be copied on assignment, but at any time, even while resting in a variable. Or, alternatively, the record objects do have persistent identity, but any reference to a record may, at any time, be replaced by a reference to another record object with the same state, but a different identity. (We may be able to say that the "At any time" is only "when a reference is dereferenced", but I'm not sure its distinguishable in practice. Not really value types, not really objects. Most like value types pretending to be objects, badly. (And the reason I say they are reference types is that it's possible that identical(x, x) gives true when x is a record reference. If they were value types with guaranteed copy-on-assignment, that identical would always give false.)
  • int, double, bool, String and Null are all immutable and canonicalized, so we can't notify whether two "identical" variables have the same reference value or just same values referred.
  • bool and Null are just three fixed values, no need to be canonicalized.
  • String is only canonicalized on the web (because the browser string type is).
  • int and double are right on.

The point of identical lying is (other than to match JavaScript) that it allows the VM to unbox and rebox numbers without worrying about preserving identity, but also without breaking the idea that all objects have identity.
It's only with records where we finally stopped pretending that, because we didn't want identical to have to recursively check record structures. Making identical too expensive would take away from its use as "fast path" in comparisons.

  • Expando have some restriction for some implementation reasons, but not for semantical reasons.

Correct. We could allow expando values on int, double, String, bool and Null values, because they do have persistent identity. They'll just never be GC'ed because a value with the same identity can always be produced.

For bool and Null, that's not particularly special, same goes for any enum, or other constant, value that it will never be GC'ed, so neither will the expando value attached to it (well, unless the expando itself goes away).

For the rest, it's undecidable whether some later computation would produce thes aem number or string, so we'd never be able to GC an attache expando value. That's not necessarily a problem, the restriction is mostly for your own protection. We could just keep a non-weak map on the side for expandos for any of these types, it would never be GC'ed, but again, very likely neither would an expando on an enum value.

That's not the same for records. Records have identity, just not persistent identity. Which means that using them as expando keys is so unpredictable that it's useless

var pair = (1, 2);
var exp = Expando<int>();
exp[pair] = 3;
// At this point, the object identity of the argument to `exp[]` may no longer exist.
print(exp[pair]); // 3 or null, no way to know.

Expandos work by attaching values to the object identity of the referenced object passed in.
Since any reference to a record object may change what it references at any time, a record object may cease to exist at any time, when the last reference to it goes away and it gets GC'ed.

from language.

Cat-sushi avatar Cat-sushi commented on September 23, 2024

Thank you for your explanation.

I've perfectly understood.
I've understood also that references mean accesses to the conceptually lasting and canonicalized instances, but are not necessarily addresses to the memory representations, in case of int, double or String.

I'm closing this issue.

from language.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.