Three hours ago, Peter Kourzanov wrote: > On Thu, 2010-12-23 at 20:39 -0500, Eli Barzilay wrote: > > Earlier today, Peter Kourzanov wrote: > > > On Wed, 2010-12-22 at 18:36 -0500, Eli Barzilay wrote: > > > > > > > You're confusing (or mixing) a local binding (let ((eqv? ...)) ...) > > > > with an implicit mutation (define eqv? ...). > > > > > > Is it? > > > > ...an implicit muatation? Yes. > > ...so different? Yes. > > ...a confusion? Thats how it seems. > > I don't agree. *sigh*... This is a frustrating mis-discussion. I said above that you're confusing the two things, to which you replied with an obscure "is it", so I answered three possible interpretation of that -- and you continue with the vagueness: if you want to discuss something then plase be more specific about what is it that you don't agree with. > 11.2.1: "The first from of define binds <variable> to a new location > before assigning the value of <expression> to it." (other forms are > trivially expressed using the first) > > That's exactly #1 (new location), #2 (setting the value) and #3 > (binding of the new location to the given name). I can only relate > #3 to the meaning of eqv? (the name) before (define eqv? ...). The location that the text refers to is due to mutable variables in Scheme. It means that bindings map identifiers too (mutable) locations rather than to values (which makes them all constant, as in other functional languages like ML). None of this happens when you *re*define a binding -- that case turns into an implicit assignment in R5RS (sans modules) but it is not intended to be a device that you'd use instead of assignment, only as a way to reload code and getting new values in effect for existing references. It also doesn't happen in R6RS where you just don't redefine bindings. > > > The way I read R6RS, (define) is supposed to (#1) allocate a new > > > location for this new eqv?, (#2) set! the result of the > > > expression to it and (#3) mutate the *binding* for eqv? in the > > > environment (or splice into parent environment when enclosed by > > > begin). At least, that's what it typically does for other > > > variables. I.e., > > > > That's r5rs w/out any module system. Not r6rs (in a library). > > Is there a difference? Let's see... Yes, there is a difference. A toplevel `define' in R5RS is analogous to a side-effect in a single ongoing repl, and in R6RS it is more like an internal define, scoped by the library it is part of. > 11.2: "Definitions may appear within a <top-level body> (section 8.1), > at the top of a <library body> (section 7.1), or at the top of a <body> > (section 11.3)." > > 8.1: "A <top-level body> is like a <library body> (see section 7.1), > except that definitions and expressions may occur in any order." > > so => not this one, (I have no idea what that "=>" stads for, what "this" refers to, and what "not" negates.) > > > And, BTW, 11.3 says that (define) is equivalent to (letrec*). So why > > > are these cases so different then? > > > > Because those are internal definitions. > > Again, what's the difference? An internal block of `define's is equivalent to a `letrec' (or a `letrec*' in R6RS), for example, this: (define x 1) (define x 2) cannot appear in an internal definition context in the same way that you cannot have two bindings for `x' in a `letrec'. This behavior makes these kinds of definitions very different than the kinds of mutations you are trying to promote (the toplevel redefinition of `eqv?'). > Let's see... > > 7.1: "A <library body> is like a <body> (see section 11.3) except that a > <library body>s need not include any expressions." > > so => not this one either, (Still no clue why you quoted that, or what the conclusion is supposed to be.) > Finally: > > 11.3: "An expanded <body> (see chapter 10) containing variable > definitions can always be converted into an equivalent letrec* > expression." > > Chapter 10 goes into fine details of how to reorder according to > 8.1. (Or why the ordering of definitions is relevant.) > > > I guess if R6RS enforced macro-implementation of (case), like > > > Haskell's Prelude, the problem would be solved (via syntactic > > > closures provided by hygiene & referential transparency of > > > syntax-rules). > > > > ?? > > Let just prescribe the "wanted" syntax-rules implementation of case > in the standard. Then there can be no confusion about its meaning > and no PhD required to understand what the standard intends but does > not say. (So far I see only one person who was confused over that.) It's the nth time that you ask to specify that `case' be implemented as a macro -- yet you haven't provided any motivation for doing so. The only thing that looks close to a reason is your desire to be able to customize the equality that it uses -- yet this doesn't require forcing a macro implementation. For example, the text could replace in the sense of `eqv?' with in the sense of the current lexical binding for `eqv?' and you get your kind of customization hook without a requirement on the implementation. As for the hook itself, there is first the question of why a hook is needed, and then there's how it should be implemented. The solution of mutating `eqv?' is pretty horrible IMO -- and it's worse when you actually want to do this by a `define'. If anything, you should go with advocating a plain `set!' which would clarify that you really want some more "hook-ish" name like `current-equality', and better to use some feature that avoids race conditions for threaded implementations (eg, racket parameters). That would be a much better suggestion, which I still won't like because of situations like: ;; my code (define (foo x) ... case ...) ;; your code (define (bar x) (parameterize ([current-equality my-equal?]) (case (foo x) [(1) (foo x)]))) In this case, the function I wrote breaks because you wanted to customize your `case'. Two outcomes of this are -- (a) you need to use the customization very carefully, as in (define (bar x) (let ([x* (foo x)] [old-eq (current-equality)]) (parameterize ([current-equality my-equal?]) (case x* [(1) (parameterize ([current-equality old-eq]) (foo x))])))) or (b) I write my `bar' in a defensive way and make sure that `current-equality' is set to `eqv?', ending with similar hair. Both of these seem much more unpleasant than passing in the equality as an additional argument to some `case-with'. -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _______________________________________________ Scheme-reports mailing list Scheme-reports@scheme-reports.org http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports