Comments (5)
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.
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.
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.
- 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
anddouble
are always auto-canonicalized (aka.identical
lies).bool
andNull
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 whenx
is a record reference. If they were value types with guaranteed copy-on-assignment, thatidentical
would always givefalse
.)
- 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
andNull
are just three fixed values, no need to be canonicalized.String
is only canonicalized on the web (because the browserstring
type is).int
anddouble
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.
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)
- Make sure type-special-casing for numbers is updated to account for extension types. HOT 5
- Are macros applied on packages too? HOT 8
- Rethink `required` to be optional for non-nullable named parameters without default values HOT 2
- Introduce abstraction for specifying "class-like" structure HOT 2
- class tear-off with extra parameters HOT 3
- Make default values of parameters parts of function type HOT 2
- Allow functions to be used directly as metadata annotations HOT 5
- Investigate the ability for macros to add mixins and interfaces HOT 2
- Use bottom-up type inference for invocations of generic functions with non-covariant parameter types
- Specify UP on extension types. HOT 4
- Can we allow `mixin on <SealedClass>`? HOT 6
- Allow resolving any identifier to its declaration in the definitions phase (phase 3) HOT 1
- Straw alternative for negative if-variables HOT 1
- Inherent extensions HOT 3
- Provide a way to fully close a type in the same library HOT 2
- Infer the return type of a cycle-free arrow getter HOT 12
- Add support for extension macros and introspection HOT 1
- Add support for extension type macros and introspection HOT 3
- Macro phases example HOT 2
- Whether local variables and method parameters should be disabled and begin with an underscore HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from language.