Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InstanceMirror : request for 'Stream onFieldChanged' member #10682

Closed
DartBot opened this issue May 15, 2013 · 9 comments
Closed

InstanceMirror : request for 'Stream onFieldChanged' member #10682

DartBot opened this issue May 15, 2013 · 9 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-not-planned Closed as we don't intend to take action on the reported issue library-mirrors type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented May 15, 2013

This issue was originally filed by ross.dart...@gmail.com


This is a feature request for dart:mirrors regarding the ability to observe changes to fields in objects.

There has been work done on observable objects in the web_ui project and now there is the mdv_observe project. I believe that arbitrary Dart objects should be observable when the user decides to enter into such a contract, and that dart:mirrors is the correct place to expose this functionality.

I would like to be able to bind arbitrary Dart objects to my user interface, and I can do this today. I can use InstanceMirror.setField(Async) and InstanceMirror.getField(Async) to perform data binding. However, there is one problem that I cannot solve, which is that if the Object I have mirrored is changed from outside of my user interface (from a remote process, for example), my user interface has no way to know about that change other than polling for new values with getField(Async). I don't think this has been or can by solved by enforcing the user to wrap all their ViewModels in some Observable type either, because they inevitably point to another plain old Dart object which is still exposed to modification from other sources.

I think this could be solved by exposing a Stream of field change events on InstanceMirror. If there are no subscribers, there should be nearly no overhead to having this. If there are subscribers, they should receive all changes to the field(s) they are subscribed to.

I hope this makes some sense. I have thought about this a lot, and I've dealt with this in .NET as well where objects that do not implement INotifyPropertyChanged have the same weakness. I would only care to have this work in the local MirrorSystem (like reflectee) but I don't see why it maybe couldn't be remote as well.

Thanks for consideration!

@DartBot
Copy link
Author

DartBot commented May 15, 2013

This comment was originally written by ross.dart...@gmail.com


I wish you could edit these posts!

'remote process' was bad choice of terms; I meant 'some service in my isolate that the ui does not talk with but which also has access to my bound data'. Perhaps that service is talking to a remote process, or just doing its own thing.

@anders-sandholm
Copy link
Contributor

Removed Type-Defect label.
Added Type-Enhancement, Area-Library, Library-Mirrors, Triaged labels.

@gbracha
Copy link
Contributor

gbracha commented Aug 24, 2013

Observability and data binding are very useful base level functionality. They do not belong in the mirror library. There is a lot of work on that elsewhere in Dart.


Added NotPlanned label.

@DartBot
Copy link
Author

DartBot commented Nov 27, 2014

This comment was originally written by dev...@futureperfect.info


#­3 I agree that object observability is a very useful base level functionality. Would there be any worth to opening a new feature request in the vein of TC39's Object.observe? Or would it be futile?

They have got this right, and it is a very compelling reason to choose Javascript over Dart. Of course there are other reasons to choose Dart, but I believe Dart needs an Object.observe if it wants to compete long-term on the client side. This was also a pain point in C# (and Java) where observability is delegated to special "observable" objects.

All objects need to be (optionally) observable, which is the fundamental flaw that Object.observe has so wisely solved for the Javascript community. I am not interested in any package or framework solution because they cannot by definition solve this correctly.

@lrhn
Copy link
Member

lrhn commented Nov 27, 2014

JavaScript's Object.observe is a very low-level feature which does not take abstraction into consideration.
It observes physical changes, not logical changes. It's like looking at syntax without considering semantics.

Object.observe only looks at object properties - it can't detect that a getter would now return a different value. It may detect multiple changes that is really only a single logical change, or it might miss a change that happens on an embedded object which isn't observed.
For example, if I make a multi-object data structure, like a linked list, then observing the root object doesn't tell you anything about the elements of the list.

It does work if you restrict your data model to be simple JSON-like objects with no behavior and no abstraction - no private fields, no computed getters, no compound structures.
Only the most primitive Dart objects are so simple.
It "works" in JavaScript because many data-models are actually this simple and nobody uses or expects encapsulation.

In short, I think observing object property changes without understanding the object's meaning is not something that scales to languages with proper abstraction.
There's probably a good reason that languages like Java and C# doesn't have observability without the object's cooperation. You need the object to cooperate with you in telling which changes are actually meaningful, or even which changes happened at all - in the private internal model that you can't, and shouldn't, see from the outside.

@DartBot
Copy link
Author

DartBot commented Nov 27, 2014

This comment was originally written by dev...@futureperfect.info


JavaScript's Object.observe is a very low-level feature which does not take abstraction into consideration.

A low-level feature is precisely what I (and others) desire. I don't want someone else's abstraction.

Object.observe only looks at object properties - it can't detect that a getter would now return a different value.

Again, this is what I want and expect.

For example, if I make a multi-object data structure, like a linked list, then observing the root object doesn't tell you anything about the elements of the list.

Again, that is what I would expect it to do (provide change notifications for the root object).

In short, I think observing object property changes without understanding the object's meaning is not something that scales to languages with proper abstraction.

Who said that I don't understand the meaning of the objects in my system? I certainly do. And I'd also like to observe them. All objects can be decomposed into the simple types.

I'm getting the feeling that a new feature request would be futile, so I will let this go back to rest.

@DartBot
Copy link
Author

DartBot commented Nov 27, 2014

This comment was originally written by greg.low...@gmail.com


It's already pretty easy to do this in dart using the observe package.

http://www.dartdocs.org/documentation/observe/0.12.1+1/index.html#observe/observe

import 'package:observe/observe.dart';
import 'package:observe/mirrors_used.dart';

class Monster extends GameObject with Observable {
  @­observable int health = 100;
}

main() {
  var obj = new Monster();
  obj.changes.listen((records) {
    print('Changes to $obj were: $records');
  });
}

@DartBot
Copy link
Author

DartBot commented Nov 28, 2014

This comment was originally written by dev...@futureperfect.info


#­7 This issue is / was about object observe as a language and / or core feature. There is a fundamental difference between that and a package solution (e.g. the observe package). With a package solution you can only observe objects that are defined according to the rules of that package. As soon as your code wants to observe an object that is created with some other package, or with no observable package at all, you will be stuck. This is the fundamental difference. If you have not run into this in building large-scale GUI applications then I admit it may be hard to appreciate the difference. I suggest to read this article if you want a primer to appreciate the difference:

http://www.html5rocks.com/en/tutorials/es7/observe/

@lrhn
Copy link
Member

lrhn commented Nov 28, 2014

I've read the Object.observe tutorial and other descriptions.

The JavaScript Object.observe functionality works in JavaScript because it works for JavaScript objects and arrays - and that's all there is. In Dart, it would be the equivalent of an observe that only works on LinkedHashMap<String,...> and growable List. That's definitely doable, but not really something you can use in practice.

I'm not opposed to having some language supported way to easily make objects observable, but I still think that it needs cooperation from the object.

A Dart object can change its implementation between a field and a getter between versions without breaking anything. If it breaks observing it (because there is no way to know when the getter changes its value), then that kind of observing is incompatible with the Dart programming model.

@DartBot DartBot added Type-Enhancement area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-mirrors closed-not-planned Closed as we don't intend to take action on the reported issue labels Nov 28, 2014
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed type-enhancement labels Mar 1, 2016
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. closed-not-planned Closed as we don't intend to take action on the reported issue library-mirrors type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants