<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    On 14.10.2010 4:14, Brendan Eich wrote:
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>
        <div>On Oct 13, 2010, at 6:56 AM, Dmitry A. Soshnikov wrote:</div>
        <br class="Apple-interchange-newline">
        <blockquote type="cite">
          <div bgcolor="#ffffff" text="#000000">Also I think now, that
            what was named as pros, i.e. ability to have funargs and
            call/apply invariants, in real, not so pros. Because users
            more likely want to catch exactly missing methods (if you
            don't like the word "methods", since there're no methods,
            there are properties, let's say -- missing properties which
            ended with `call expression` at the call-site). </div>
        </blockquote>
        <div><br>
        </div>
        That's not our experience with E4X (ECMA-357), which specifies
        XML methods as invoke-only. They seem to be normal
        function-valued properties of XML.prototype, but getting one by
        name on an XML instance in a non-callee expression context
        instead tries to find an XML child element or elements of the
        method's name, returned as a list.</div>
      <div><br>
      </div>
      <div>Some of this is peculiar to E4X, but the invoke-only nature
        of the methods, per-spec, is not. And it breaks apply and
        functional programming, so we extended E4X with the function::
        pseudo-namespace to allow one to extract methods from XML
        instances.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Yes, I'm aware of it. However, you mention a similar end result
    (inability to extract a function with a normal (accessor) syntax),
    but with completely different reason. In case of EX4 you talk about
    the existing real methods. In case of proxies, we talk about
    non-existing property (which is activated with a next call
    expression). The difference is: in first case a user really deals
    with existing stuff and expect the functions to be extracted (of
    course in this case ECMA-357 had to do something --&nbsp; provide :: --
    to allow this). In the later one, at the first place, a user wants
    to catch the call expression.<br>
    <br>
    Yeah, it's a good example, but I see that similarity of the end
    result is used to apply it to the different _reasons_ (messing the
    concepts). And in case of the first reason -- yes, it's critical. In
    case of the second one -- not so or even non-critical. Because,
    repeat, catching such cases (missing methods) a user may not want to
    deal with an alive function, since it's just a signal to do to
    something (to handle the _case_). Below I provide test sources (as
    you asked) to complete my position (showing that implementations
    with 'get+fn' + 'noSuchMethod' can even _co-exist_ -- and everyone
    will be happy).<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Others using __noSuchMethod__ are happier as you say, because
        (for example) they are Smalltalkers (Bill Edney is on this list)
        who pretend there are only method calls (message sends), never
        properties or first-class functions.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Yes, in systems which has second-class functions it's easier to
    handler this case (there is no need to return a function). However,
    it's not just because there are first-class function. E.g. Ruby also
    has them, but having them, it distinguishes call expression syntax
    in different cases: a method is called with (), a lambda is called
    with `.call` method:<br>
    <br>
    # global catcher for missed methods<br>
    <br>
    def method_missing(name, args)<br>
    &nbsp; p "Method: ", name, "Args: ", args<br>
    end<br>
    <br>
    # a method "foo"<br>
    # which returns a lambda --<br>
    # a functional first-class object (also, a closure);<br>
    # the lambda itself just prints 10<br>
    <br>
    def foo<br>
    &nbsp; lambda {<br>
    &nbsp;&nbsp;&nbsp; p 10<br>
    &nbsp; }<br>
    end<br>
    <br>
    # we call "foo" method (notice, with () syntax),<br>
    # and then call with different syntax -- via .call, the<br>
    # returned lambda<br>
    <br>
    foo().call # 10<br>
    <br>
    # however this case is<br>
    # caught with method_missing<br>
    <br>
    nonExisting(2) # "Method: " :nonExisting, "Args: " 2<br>
    <br>
    But this is just -- a "by the way", Ruby is irrelevant with ES and
    this mailing list (this example is just to mention that the
    discussed issue is not just because there are first-class
    functions). I like more though that ES has the same syntax for these
    cases.<br>
    <br>
    Besides, I understand that ES has similar to Python implementation
    with "only properties", and moreover, Python also has no
    __no_such_method__ hook, only its __get__ and __getattr__ (also
    around the Internet there are some shims of Ruby's `method_missing`
    for Python with returning every time a function from the __get__).
    But, having similar to Python implementation, JS can go further and
    better.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>But that happiness is not universal, so your "not so pros"
        judgment is not true for everyone.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    I understand, however I'd like to notice that I'm not judging, but
    objectively analyzing.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Should we support everyone even if it makes the Proxy system
        more complicated and allows for not-quite-function methods?</div>
      <div><br>
      </div>
      <div>Our decision was "no". You're asking us to revisit to support
        the some (not all) developers who want to make
        not-quite-function methods. That's a fair request but I think
        you need to do more than assert that the resulting complexity is
        not a problem. Further below, I'll do some legwork for you.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    OK, I understand this position quite clearly. I'll also show further
    below that there can be possible compromise with co-existing both
    approaches.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div><br>
        <blockquote type="cite">
          <div bgcolor="#ffffff" text="#000000">And funargs/apply
            invariants should be leaved for _real functions_ (existing
            or ad-hoc, explicitly returned from the `get`).</div>
        </blockquote>
        <div><br>
        </div>
        Why shouldn't all methods including missing ones be _real
        functions_? Why complicate the domain of discourse with real and
        not-quite-real functions?</div>
      <div><br>
      </div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Assuming this, I try to see on the issue from the position that
    catching a missed method, a user deals with a _fact_, with just a
    _signal_ about this _situation_ (that a method is missing), but not
    with a method itself. And he can handle this situation.<br>
    <br>
    What in contrast proposes the implementation with returning each
    time a function?<br>
    <br>
    (I in advance apologize for such a simplified style of description
    and long text below, it's just easier for _myself_ (and first of all
    -- only for myself), for not to confuse with all cases; I just try
    to analyze and see all available pros and cons).<br>
    <br>
    - I want to catch missing method, can you (a system) handle this
    _situation_?<br>
    - Which missing methods? You don't have any missing method.<br>
    - Really?<br>
    - Yes, try it yourself:<br>
    <br>
    var o = {};<br>
    <br>
    o.n();<br>
    o.foo();<br>
    o.bar();<br>
    <br>
    ... All do work. I.e. any missing property, for you, is a method. Do
    whatever you want with it. Call e.g. your noSuchMethod function
    inside it.<br>
    - Hm, but how can I test whether a some method (or a property)
    exists on my object?<br>
    <br>
    Obviously, the approach:<br>
    <br>
    if (!o.n) {<br>
    &nbsp; o.n = function () {};<br>
    }<br>
    <br>
    or even so:<br>
    <br>
    if (typeof o.n != "function") {<br>
    &nbsp; o.n = function () {};<br>
    }<br>
    <br>
    won't work. Why should I get always a "function" for every reading
    of a (non-existing) property?<br>
    <br>
    - Hm... use `in` operator as a variant then for this case:<br>
    <br>
    if (!("n" in o)) {<br>
    &nbsp; o.n = function () {};<br>
    }<br>
    <br>
    - Yeah, right, it may help. But you conclude that the case with
    reading a property for such a check is broken? Btw, I saw it widely
    used in current scripts for providing missing stuff (e.g. if
    (!Array.prototype.forEach) { ... }).<br>
    - Unfortunately. it's broken.<br>
    - Hm, i.e. a property "exists" -- `o.n` (it's a function as I see),
    and at the same time -- does not -- "n" in o -- false?<br>
    - Unfortunately. Yep.<br>
    <br>
    - Interesting... And what about if I want to handle both -- reading
    a property and calling a method in one `get` of a proxy?<br>
    - No, you can't. Didn't you realized it still? -- You have always
    only functions in this case. Forget about non-functional properties.
    There is no such API. You can handle _either_ properties, _or_
    functions via `get`.<br>
    <br>
    - Well, OK... Let's assume it... And what about the === operator? Is
    it also broken?<br>
    - No, why is it broken? Just cache your functions by the name. Yeah,
    it will take a bit of code (which you possibly will repeat every
    time in such cases, but...)<br>
    - Yeah, right. Fair enough (though I thought the same). Moreover, it
    will work with assigning to another name:<br>
    <br>
    foo.bar == foo.bar; // true<br>
    foo.baz = foo.bar;<br>
    foo.baz == foo.bar; // also true, since foo.baz exists now (of
    course if we return _existing_ properties _as is_)<br>
    <br>
    Seems OK. Though, I see one more place which should be patched:<br>
    <br>
    // a non-existing "foo.bar"<br>
    foo.bar; // cache it at first reading<br>
    foo.bar(); // alerts e.g. 1, first implementation<br>
    <br>
    // it's existing now<br>
    foo.bar = function () {<br>
    &nbsp; alert(2);<br>
    };<br>
    <br>
    foo.bar(); // alerts 2<br>
    <br>
    // delete it<br>
    delete foo.bar;<br>
    <br>
    foo.bar(); // alert 1?<br>
    <br>
    So, besides that small code with caching in `get`, we need some
    _invalidating cache_ logic in the `delete` trap. It seems that all
    this "magic" code combines in some pattern (possibly, there is a
    sense to encapsulate and abstract it in some sugar, don't know).<br>
    <br>
    - Another minor thing -- `delete` does not really delete.<br>
    <br>
    delete foo.bar;<br>
    foo.bar; // function<br>
    <br>
    - Right, but what are you trying to delete? A non-existing property?<br>
    - Yes, I understand, but it just looks a bit strange --
    non-existing, but still always is equal to some _function_.
    Moreover, with our caching system, I see that this is a _very
    consistent_ property in it's equality invariant:<br>
    <br>
    foo.bar == foo.bar; // always (correctly) true<br>
    <br>
    but it always a _function_. I could understand that it can be for
    non-existing properties where undefined === undefined, but here are
    the "existing" functions.<br>
    - Well...<br>
    <br>
    - OK, and what about the prototype chain? Where should I put this
    proxy object in order to prevent of catching of all my missing
    properties (because I want to catch them from other objects in the
    prototype chain, to which these properties belong)?<br>
    <br>
    Object.prototype.foo = 10;<br>
    <br>
    "foo" in o // true, OK<br>
    o.foo; // but it's a _function_, not 10<br>
    <br>
    - Doesn't `o` inherit from the `Object.prototype`?<br>
    - No, it does inherit, but since you don't have a function call, you
    won't reach `Object.prototype`. Though, you can reach
    Object.prototype's methods (yes, with a bit overhead 'cause it's
    reached via our wrapper).<br>
    <br>
    - So, o.toString() calls Object.prototype.toString (in case of
    course I inherit `toString` from the Object.prototype), but at the
    same time o.toString !== Object.prototype.toString, right? It seems
    === is broken again.<br>
    - Unfortunately.<br>
    <br>
    Did I miss something?<br>
    <br>
    OK, so what pros and cons we have:<br>
    <br>
    Pros:<br>
    <br>
    1. we can handle call-expressions: foo.bar()<br>
    2. functions may be applied, passed as functional values (functional
    WTF!): foo.bar<br>
    3. with a little "magic" (caching by name) we can even have them
    equal to each other: foo.bar === foo.bar<br>
    <br>
    Cons:<br>
    <br>
    1. a non-existing property is always a function: foo.bar // function<br>
    2. at the same time, it behaves as _consistently existing one_,
    including equality: foo.bar === foo.bar (with some the mentioned
    "magic"); and at the same time we can't delete it.<br>
    3. if we want to apply some patch for an object depending on
    existence of some property -- we can't do it using reading accessor
    of the property (i.e. cases with if (!foo.bar) or if (typeof foo.bar
    ... won't pass), only `in` operator may help. Yeah old scripts with
    testing if (!foo.bar) {...} should be rewritten (Is WEB really
    shouldn't be broken?)<br>
    4. regarding the same `in`, a property isn't here -- "foo" in bar --
    false, but it's always here -- foo.bar // always a function<br>
    5. we can't read correctly _existing_ properties from the prototype
    chain regarding objects which are deeper than our proxy, because the
    proxy will catch them and return its function. In case when a
    prototype's property is really a function, it's OK -- we just wrap
    it (with a bit overhead, let it be). But in case of _non-functions_,
    sorry, please get a function from a proxy anyway. This step assumes
    that a proxy object should be placed as deeper in the prototype
    chain as possible. Though, it cannot be placed deeper than
    Object.prototype. <br>
    <br>
    - OK, we have more cons, I see. What do you propose than? You can't
    just judge this approach without suggestions.<br>
    <br>
    What about to have `noSuchMethod` _additionally_ to the `get`? It
    will catch only missing properties, but: not _just_ missing
    properties, but missing properties which use a call expressions at
    call-sites. Thus, we can combine two approaches allowing a user to
    choose how to handle the case of missing _method_.<br>
    <br>
    handler.get = function (r, name) {<br>
    &nbsp; if (name == "baz") {<br>
    &nbsp;&nbsp;&nbsp; return function () { ... }; // and cache "baz" name if you wish<br>
    &nbsp; }<br>
    &nbsp; // other cases<br>
    &nbsp; return object[name];<br>
    };<br>
    <br>
    handler.noSuchMethod = function (name, args) {<br>
    &nbsp; return this.delegate[name].apply(this, args);<br>
    };<br>
    <br>
    Then we have:<br>
    <br>
    var foo = {};<br>
    <br>
    // reading of a non-existing property<br>
    foo.bar; // correctly undefined!, but not a function<br>
    <br>
    foo.baz; // function, ad-hoc trapped by the `get`<br>
    foo.baz(); // OK<br>
    foo.baz.apply(null); // OK<br>
    foo.baz === foo.baz; // true with caching<br>
    <br>
    // try to call non-existing property:<br>
    // first, `get` is&nbsp; fully trapped. At this<br>
    // step, `get` may return also a function -- then<br>
    // noSuchMethod won't be called;<br>
    // However, in our case `undefined` is returned, and we have:<br>
    <br>
    foo.bar(1, 2, 3); // noSuchMethod is called with passing message to
    a delegate object<br>
    <br>
    Pros:<br>
    <br>
    1. we can handle call-expressions: foo.bar()<br>
    2. we can differentiate (by the call-site context) missing
    properties from missing "methods"<br>
    <br>
    ALL mentioned above invariants do work:<br>
    <br>
    3. foo.bar === foo.bar // in any case! (with logical `get` trap of
    course)<br>
    <br>
    4. if (!foo.bar) foo.bar = {} // also OK<br>
    <br>
    5. foo.toString === Object.prototype.toString; // true!<br>
    <br>
    6. "bar" in foo; // false, also OK<br>
    <br>
    Cons:<br>
    <br>
    1. Unable to apply/call `foo.bar`, but at the same time able to call
    it -- foo.bar()<br>
    <br>
    * Note: excluding a case of ad-hoc `get`: in this case if
    non-existing "bar" is returned from `get`, then there is no even
    this cons -- we can apply it and call it.<br>
    <br>
    That's it.<br>
    <br>
    E.g. who want to build it as in previously proposed scheme -- with
    using [ only `get` + caching + invalidating the cache + broken ===,
    in, reading property tests ] -- they may still use it. All is needed
    just _not to define noSuchMethod_ on the handler. If nevertheless
    it's defined on the handler _and_ a callee context is a call
    expression -- it's called. It seems quite straightforward and
    _practical_.<br>
    <br>
    (Sorry again for this long description, however it's needed, I'll
    refer it when will explain to JS programmers the current sate of
    noSuchMethod in ES and why it's so).<br>
    &nbsp;<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>
        <blockquote type="cite">
          <div bgcolor="#ffffff" text="#000000"> Moreover, as it has
            been mentioned, such returning has broken === invariant
            anyway (and also broken invariant with non-existing
            properties).<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        Proxy implementors can memoize so === works. It is not a ton of
        code to write, and it gives the expected
        function-valued-property-is-method semantics. Here is&nbsp;the
        not-all-that-inconvenient proxy code:</div>
      <div>
        <div><font class="Apple-style-span" face="'Courier New'"><br>
          </font></div>
        <div><font class="Apple-style-span" face="'Courier New'">function
            makeLazyMethodCloner(eager) {</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp;var
            cache = Object.create(null);</font></div>
        <div><span class="Apple-style-span" style="font-family: 'Courier
            New';">&nbsp;&nbsp; &nbsp;var handler = {</span></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp;get: function (self, name) {</font></div>
        <div><span class="Apple-style-span" style="font-family: 'Courier
            New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (!cache[name])</span></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cache[name] = Proxy.createFunction({},</font><font
            class="Apple-style-span" face="'Courier New'">&nbsp;function () {</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return eager[name].apply(eager, arguments);</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</font><span class="Apple-style-span"
            style="font-family: 'Courier New';">);</span></div>
        <div><span class="Apple-style-span" style="font-family: 'Courier
            New';">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return cache[name];</span></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp;}</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp;};</font></div>
        <div><span class="Apple-style-span" style="font-family: 'Courier
            New';">&nbsp;&nbsp; &nbsp;return Proxy.create(handler,
            Object.getPrototypeOf(eager));</span></div>
        <div><font class="Apple-style-span" face="'Courier New'">}</font></div>
        <div><font class="Apple-style-span" face="'Courier New'"><br>
          </font></div>
        <div>A little test code:</div>
        <div><font class="Apple-style-span" face="'Courier New'"><span
              class="Apple-style-span" style="font-family: Helvetica;"><br>
            </span></font></div>
        <div><font class="Apple-style-span" face="'Courier New'">var o =
            {m1: function () { return "m1"}, m2: function () { return
            "m2"; }};</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">var p =
            makeLazyMethodCloner(o);</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">print(p.m1());</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">print(p.m2());</font></div>
      </div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Yes, thank you Brendan, I completely understand it. As you possibly
    saw I also talked about caching in the previous letters.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Some subtle things here:</div>
      <div><br>
      </div>
      <div>* The missing fundamental traps in the handlers are filled in
        by the system. This is a recent change to the spec, implemented
        in SpiderMonkey in Firefox 4 betas.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Is that standard forwarding `noopHandler` mentioned before? Yeah,
    great. It is useful. Though, possibly all implicit traps may bring a
    little overhead (if e.g. a user does not want to trap `delete`, but
    it will be trapped). From the other hand, yes, it's very convenient.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>* Even p.hasOwnProperty('m1') works, because the get trap
        fires on 'hasOwnProperty' and clones eager['hasOwnProperty']
        using a function proxy, even though that method comes from
        Object.prototype (eager's Object.prototype). The hasOwnProperty
        proxy then applies Object.prototype.hasOwnProperty to eager with
        id 'm1'. No get on 'm1' traps yet -- no function proxy creation
        just to ask hasOwnProperty.</div>
      <div><br>
      </div>
    </blockquote>
    Yep, at least properties with call-expressions are caught. But
    unfortunately, not other properties. And also p.hasOwnProperty !==
    Object.prototype.hasOwnProperty<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>* Both p.m1 and p.m1() work as expected. Only one kind of
        function.</div>
      <div><br>
      </div>
    </blockquote>
    Yes, this is a pros mentioned above.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Now consider if you had a third parameter to the 'get' trap
        to signal callee context vs. non-callee context. You'd still
        want to proxy the functions, that doesn't get simpler just due
        to a change of trap parameters. You'd still want to cache for
        identity. But you would have made invoke-only methods.</div>
      <div><br>
      </div>
      <div>Ok, let's give up on functional programming and cached
        methods. Here' s my version written to use only
        __noSuchMethod__, no proxies:</div>
      <div><br>
      </div>
      <div>
        <div><font class="Apple-style-span" face="'Courier New'">function
            makeLazyMethodCloner(eager) {</font></div>
        <div><span class="Apple-style-span" style="font-family: 'Courier
            New';">&nbsp;&nbsp; &nbsp;return
            Object.create(Object.getPrototypeOf(eager), {</span></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp;__noSuchMethod__: {</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp;value: function (name, args) {</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return eager[name].apply(eager, arguments);</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp; &nbsp; &nbsp;}</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp; &nbsp;
            &nbsp;}</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">&nbsp;&nbsp; &nbsp;});</font></div>
        <div><font class="Apple-style-span" face="'Courier New'">}</font></div>
        <div><font class="Apple-style-span" face="'Courier New'"><br>
          </font></div>
      </div>
      <div>9 lines instead of 13, but broken functional programming
        semantics -- you cannot extract p.m1 or p.m2 and apply them
        later, pass them around, etc.</div>
      <div><br>
      </div>
      <div>What good would result from this? Again, our view in TC39 is
        "not much".</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    But I propose to have `noSuchMethod` trap _in addition_ to `get`.
    And this `noSuchMethod` should be called _only_ if (1) it's defined
    on the handler AND (2) _only_ after `get` _completely finished_ its
    work AND (3) if `get` returned undefined AND (4) call-site has a
    call-expression AND (5) requested property is not in object (to
    diffirentiate from the real undefined value).<br>
    <br>
    What the reason that this is bad somehow? Only pros. Combination of
    `get` and `noSuchMethod` is a good way which may cover most cases
    (including with apply invariant -- in this case an ad-hoc case for
    non-existing property is written in `get`).<br>
    <br>
    Everyone seems will be happy from this position, from the
    compromise. Those who don't wanna see noSuchMethod -- please, nobody
    prevents you, just don't use it, but use the previous scheme with
    `get+fn` -- it's still _completely avaliable_ with _all its pros and
    cons_ (mostly cons as we see), nobody said that it shouldn't be
    used. We don't need even third argument for `get` 'cause it really
    will just complicate the handling. But to have _additionally_
    noSuchMethod -- is good. Let it be. Who will want to use it -- they
    will use. Who won't -- it's their right, they won't.<br>
    <br>
    Where am I wrong?<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Note that I used a mechanical, consistent coding style
        ("JSK&amp;R", &nbsp;{ on same line as function, newline after {), so
        the comparison is apples to apples. Is the broken semantics
        really worth four lines of savings?</div>
      <div><br>
      </div>
    </blockquote>
    Yeah, right, but the first approach has also broken semantics in
    some/many places.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>So, no fair asserting "practically it's unsoundly complicated
        and inconvenient". And please stop invoking "ideology" as a
        one-sided epithet to throw against Tom or TC39.</div>
    </blockquote>
    <br>
    With all respect, let me mention that I do not discuss here persons
    (and moreover do not throw against everyone), I'm not so interested
    in discussing persons here -- neither Tom, nor (excuse me), you, nor
    TC39. I also do not judge. What I do, is try to explain which issues
    I found during was playing with proxies, which pros and cons
    objectively I see and propose alternative variants. I polite with
    everyone here and talk with respect, but at the same time, excuse
    me, I do not need a permission to ask questions -- independently,
    whether questions seems pleasant or not for someone.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>Please do start showing examples, specifically an
        apples-to-apples comparison with __noSuchMethod__ that is
        significantly simpler. I don't see it.</div>
      <div><br>
      </div>
    </blockquote>
    <br>
    Yes, right. So I did above.<br>
    <br>
    Dmitry.<br>
    <br>
    <blockquote
      cite="mid:3798FD9C-B610-4279-A4B5-9B88588E7D2A@mozilla.com"
      type="cite">
      <div>/be</div>
    </blockquote>
    <br>
  </body>
</html>