> On Mar 26, 2016, at 9:12 AM, Matthew Flatt <[email protected]> wrote: > > At Fri, 25 Mar 2016 22:13:16 -0400, Matthias Felleisen wrote: >> >> Consider this program (a poem of a real problem I encountered): >> >> #lang racket >> >> (module server racket >> (provide c%) >> >> (define c% >> (class object% >> (super-new) >> (define/public (m) 0)))) >> >> (module client racket >> (require (submod ".." server)) >> >> (define-local-member-name m) >> >> (define d% >> (class object% >> (super-new) >> (define/public (m o) >> (displayln (interface->method-names (object-interface o))) >> (send o m)))) >> >> (module+ test >> (require (submod "..")) >> (send (new d%) m (new c%)))) >> >> (require (submod 'client test)) > > The error message should be improved to say something about `m` being a > local name, but the failure to call a method is certainly as intended. > That is, the use of `m` as a method name in a given scope is intended > to be statically the same in all forms that involve a method name, > including both `define/public` and `send`.
I think that this is the best workable proposal, especially if inside of DrRacket, the ‘m’ in (send o m) were highlighted. It would have saved me a few minutes. (Perhaps I should make my modules even smaller than 900 lines. > I don't get the "referentially transparent" suggestion. The `(send o > m)` call belongs to the `server` module, not whatever object is the > value of `o` dynamically. If you think of names as things that stand for ‘real' values and that ‘standing for’ is a substitution, you must acknowledge Quine’s observation that some positions in a language (technically sentences in a language) are referentially transparent — you can replace equals by equals there — and others are opaque — don’t perform substitution there. [Our poor simple-minded cousins in the FP community jumped from there to ‘referentially transparency’ (as a good thing) and never recovered.] My mind considers the m position in (send o m a …) a referentially opaque position. Hence define-local-member-name, which substitutes names through a scope, should not replace this m — even if m is in its list of names. Similarly, in (printf “(send o m 1)”) define-local-member-name should not peek inside the quotes. [This example is directly derived from Quine’s treatise on language and everyone tends to agree. Other positions in a language are subject to conversations among designers.] > I could imagine making the example work by redefining local names for > `send` as implying a dynamic search: first for the local `m`, then > whatever member name the local definition shadows, and so on. In the > example below, the final call would then produce 'b instead of 'a. > > A search doesn't seem like a good idea to me. ... > But you didn't say anything about a search, and I'm not sure what you > had in mind. It's just my attempt to make sense out of what local names > could mean to make your example produce 0 instead of an error. After sending my original message, I thought thru solutions and search came to mind as the only obvious one in a dynamically typed language. I am opposed to search on grounds of efficiency; we need to keep ‘send’ as a ‘constant’ time check for the method. Programmers expect that. In languages that do not treat ‘send’ as a macro and in statically typed languages (even unsoundly typed ones such as C++), I think it’s perfectly okay if a ‘friend’ method m in C refers to a public method ‘m’ in class D. That’s what I had imagined and that’s why I sent the message (though I am hoping for an error message). More generally, though, I think this problem might be a symptom of a hole in our understanding of scope and how macros relate to scope (which is why I bothered to write a long subject/message in the first place). Perhaps a macro ought to be able to specify that a certain position in the surface syntax belongs to ‘it’ and not the surface scope. If we could find other instances of this problem, it would definitely be worth our while to investigate. As is, I will leave it at the improved error message. — Matthias -- You received this message because you are subscribed to the Google Groups "Racket Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/371CAB35-512A-41D0-8298-42931525B8D1%40ccs.neu.edu. For more options, visit https://groups.google.com/d/optout.
