Coder Social home page Coder Social logo

Comments (13)

sethladd avatar sethladd commented on August 19, 2024

Awesome, thanks Greg! We definitely had libraries like mustache in mind. :)

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

Assuming that @mustache can be an instance of a subclass of Reflectable, class Bar is already marked for reflective use. With that, the following should be very near to working code (PS: to be implemented! -- but plausible):

    var instance = mustache.reflect(object);
    var field = instance.type.instanceMembers[new Symbol(name)];
    if (field == null) return _noSuchProperty;

    var invocation = null;
    if ((field is VariableMirror) || ((field is MethodMirror) && (field.isGetter))) {
      invocation = instance.invokeGetter(field.simpleName);
    } else if ((field is MethodMirror) && (field.parameters.length == 0)) {
      invocation = instance.invoke(field.simpleName, []);
    }
    if (invocation == null) {
      return _noSuchProperty;
    }
    return invocation.reflectee;

The use of new Symbol(name) is not good, this may cause problems during compilation (esp. for minification), but for the given purpose it might be possible to use const Symbol(_)?

The names VariableMirror, MethodMirror, etc., have a different meaning, because they will be the classes defined in package:reflectable/mirrors.dart rather than the ones from dart:mirrors (but they are by design identical, except for a couple of details that mark a desired development of dart:mirrors: for instance getField will be renamed to invokeGetter and getField is @deprecated in Reflectable).

So, with the current plans for Reflectable the above should not be too hard (except for that new symbol, which is a general issue rather than a Reflectable problem).

from reflectable.dart.

xxgreg avatar xxgreg commented on August 19, 2024

Thanks for the update ;)

The use of new Symbol(name) is not good

Agreed, but this is required if the name of the symbol comes from template source code which is not statically known at compile time.

For templates which are known at compile time, I could potentially write a transformer which pulls out the symbol names ahead of time - though this would break some of the more obscure dynamic features of mustache.

I think in reality it would probably be better if the user of the mustache library was able to annotate the classes they passed to mustache to omit unneeded fields/methods. Other options to reduce compile size would be for the end-user to make a wrapper class containing only the fields accessed by the template, or passing all of the data in a map.

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

.. I'm gathering info about new Symbol(..), will return when I have it ..

from reflectable.dart.

jmesserly avatar jmesserly commented on August 19, 2024

.. I'm gathering info about new Symbol(..), will return when I have it ..

nice! Ideally, new Symbol is fine, because the set of names that make sense to reflect on is constrained by Reflectable's capabilities. If I don't have capability to reflect on something, then dart2js can freely rename those identifiers in those classes/libraries, regardless of any new Symbol(str) in the code. But if I have marked something @mustache then it probably can't rename things mustache can access.

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

If 'the set of names that make sense to reflect on is constrained by Reflectable's capabilities' then it should be possible to rely on 'const Symbol(..)' only, because Reflectable will only reflect on a class if it is statically known to require that capability, and only on names declared in that class or reachable through static analysis from there: All static information. With 'const Symbol(..)', the problem is gone.

About renaming: That sounds like minification, which was also the first thing I mentioned. But I still expect to hear more about the real issues, which may or may not be minification.

from reflectable.dart.

jmesserly avatar jmesserly commented on August 19, 2024

consider example from the start of the thread:

   var template = new Template('{{ foo }}');
   var output = template.renderString(new Bar());  // output = 42

   @mustache
   class Bar {
      get foo => 42;
   }

@mustache uses new Symbol in its implementation. However, the set of reflectable names is only "foo". I'm arguing that new Symbol is fine to use in @mustache implementation.

One thing that might help Reflectable is if it made the symbols itself:

   var instance = mustache.reflect(object);
   var field = instance.type.instanceMembers[mustache.newSymbol(name)];
   if (field == null) return _noSuchProperty;
   // ... code from before ...

Not sure if that helps you, but you can now tell that "name" is only one of the things the mustache constant is reflecting on.

from reflectable.dart.

jmesserly avatar jmesserly commented on August 19, 2024

(maybe we're totally agreeing and I just misunderstood, which is common. In which case, I apologize in advance :) )

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

I think we agree pretty much. ;) But, specifically about the
predictability of the value of name: How do you know that there won't be
assignments to innerHTML somewhere in a polymer context, such that you
end up with new Symbol(name) where name == "someOtherString"? This is
probably not relevant for the mustache library in isolation, but I'm sure
it could pop up in polymer, and it's in general a very interesting problem:
Maybe there are some specific kinds of dynamism causing massive size or
speed penalties that are not actually required? In that case I would like
to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.

By the way, I still haven't gotten a clear explanation about why new Symbol(_) would be so expensive in a system where dart:mirrors is not
imported, but it is obviously necessary to somehow retain the source level
name and a mapping to the "compiled name" of anything that you want to
reflect over (using any kind of reflection support, including Reflectable),
and minification is a typical example of a transformation that introduces
such "complied names".

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

Two crucial situations for new Symbol(..) are noSuchMethod and dart:mirrors. If a comparison is made in an implementation of noSuchMethod using a new Symbol(..) in order to do something specific when a specific method is called (say, methodWithLongName), then we must be able to perform the same mapping that was done by minification. So if methodWithLongName was minified to iA then the Invocation provided as an argument to noSuchMethod will contain #iA and a comparison with #methodWithLongName will yield false even though it is the right method. So we need to translate the string 'methodWithLongName' dynamically to 'iA' before we create the new symbol and compare the two. This can only be done if we know something about the mapping done by minification, and in general we need to know the entire mapping---which will to some extent undo the effect of minification in the first place. A similar situation arises if we wish to create a new Symbol(..) and then use that with instanceMirror.invoke or a similar feature in dart:mirrors.

The real danger as that we "only need one dynamic symbol", but then the compiled output grows substantially because we are forced to provide a minification mapping for every symbol/identifier in the program.

from reflectable.dart.

jmesserly avatar jmesserly commented on August 19, 2024

[...] In that case I would like
to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.

Ah, thanks for writing that. Yeah makes sense and totally agree.

The real danger as that we "only need one dynamic symbol", but then the compiled output grows substantially because we are forced to provide a minification mapping for every symbol/identifier in the program.

Interesting. Would it help if reflectable had a different kind of Symbol? Since mustache is using new Symbol, but they aren't going to compare it against a noSuchMethod Symbol, it would maybe be nice if there was a way to communicate that to the compiler.

from reflectable.dart.

alan-knight avatar alan-knight commented on August 19, 2024

I thought the point of Reflectable was that we would say for which classes
we need this information. So if I've said that my class is Reflectable in
the names of attributes, then creating symbols for those attributes
dynamically from the content of the HTML file shouldn't affect size. I've
told it I want exactly the names of the things in the classes I've
annotated.

It does mean that I can't reduce those names further, but that's presumably
a very small saving.

On Fri, Mar 13, 2015 at 1:01 PM John Messerly [email protected]
wrote:

[...] In that case I would like

to be able to add some extra constraints in specific contexts, such that we
could get a good size/speed performance, and then programmers using it
would just have to avoid some excessively dynamic constructs. They might
not need them at all, at least if they make a habit of finding more static
alternatives.

Ah, thanks for writing that. Yeah makes sense and totally agree.

The real danger as that we "only need one dynamic symbol", but then the
compiled output grows substantially because we are forced to provide a
minification mapping for every symbol/identifier in the program.

Interesting. Would it help if reflectable had a different kind of Symbol?
Since mustache is using new Symbol, but they aren't going to compare it
against a noSuchMethod Symbol, it would maybe be nice if there was a way to
communicate that to the compiler.


Reply to this email directly or view it on GitHub
#1 (comment).

from reflectable.dart.

eernstg avatar eernstg commented on August 19, 2024

On Fri, Mar 13, 2015 at 9:01 PM, John Messerly [email protected]
wrote:

[...]

The real danger as that we "only need one dynamic symbol", but then the
compiled output grows substantially because we are forced to provide a
minification mapping for every symbol/identifier in the program.

Interesting. Would it help if reflectable had a different kind of Symbol?
Since mustache is using new Symbol, but they aren't going to compare it
against a noSuchMethod Symbol, it would maybe be nice if there was a way to
communicate that to the compiler.

We actually discussed exactly that idea recently, and we may actually end
up doing something like that, or even using strings rather than symbols (so
we'd have a String as the first argument to 'invoke', etc.). The trade-off
to consider is that canonicalized "string-like" values are cheap to
compare, but canonicalization has a similar cost as one string comparison
in the first place.

best regards,

Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

from reflectable.dart.

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.