(let [fnmaker4 (fn [coll] (fn [n] (nth coll n)))
      ints (range)]
  (= (fnmaker4 ints) (fnmaker4 ints)))

You want to make it impossible to compare functions that close over
infinite sequences? What is the point of being able to compare
functions if there are cases in which using the functions will
succeed, and the existing comparison strategy would not cause errors,
but your new proposal does?

Similarly, if you try to eval such a function, your proposed function-
eval semantics would, as I understand it, store its closed-over values
in a class constant somewhere. Then there's some secret place holding
onto the head of my lazy sequences for me? No thanks.

On May 5, 1:04 pm, Ken Wesson <kwess...@gmail.com> wrote:
> This is another case of function-object evaluation acting hinky, actually.
>
> Specifically, (eval (id 7)) is evaluating a list of (id 7), not ('id
> 7). As near as I can figure out, rather than embed the function object
> reference into the code OR complain, it is creating a new instance of
> its class with newInstance, more or less in the manner I suggested in
> another thread recently -- the failure with closures happening because
> it doesn't check for closures and closures don't have a public
> no-argument constructor, so need special handling (and preservation of
> the arguments they were constructed with -- the closed-over values).
>
> A longer-term fix might be to make instances of the function
> superclass generated by (fn [foo] bar) (but not all IFns!) compare
> equal if their exact classes are equal and, in the case that they are
> closures, the closed-over values compare equal. This doesn't break the
> expected semantics that functions that behave differently should
> compare UNequal, but allows functions to be represented as constructor
> calls to their classes and then reconstructed without breaking
> equality.
>
> In particular, we don't need to use eval to get hinky function
> equality semantics already:
>
> user=> (defn fn-maker1 [] (fn [] 3))
> #'user/fn-maker1
> user=> (= (fn-maker1) (fn-maker1))
> false
> user=> (defn fn-maker2 [x] (fn [] x))
> #'user/fn-maker2
> user=> (= (fn-maker2 3) (fn-maker2 3))
> false
> user=> (= (fn-maker2 3) (fn-maker2 4))
> false
> user=> (defn fn-maker3 [x y] (fn [z] (+ (* z x) y)))
> #'user/fn-maker3
> user=> (= (fn-maker3 1 2) (fn-maker3 1 2))
> false
> user=> (= (fn-maker3 1 2) (fn-maker3 2 1))
> false
>
> Ideally, the results would be this instead:
>
> user=> (defn fn-maker1 [] (fn [] 3))
> #'user/fn-maker1
> user=> (= (fn-maker1) (fn-maker1))
> true ; conceptually identical functions
> user=> (defn fn-maker2 [x] (fn [] x))
> #'user/fn-maker2
> user=> (= (fn-maker2 3) (fn-maker2 3))
> true ; conceptually identical functions
> user=> (= (fn-maker2 3) (fn-maker2 4))
> false ; genuinely not the same
> user=> (defn fn-maker3 [x y] (fn [z] (+ (* z x) y)))
> #'user/fn-maker3
> user=> (= (fn-maker3 1 2) (fn-maker3 1 2))
> true ; conceptually identical functions
> user=> (= (fn-maker3 1 2) (fn-maker3 2 1))
> false ; not the same:
> user=> ((fn-maker3 1 2) 10)
> 12
> user=> ((fn-maker3 2 1) 10)
> 21
>
> Now, fn-maker3 could have produced (fn [z] (+ x y z)) in which the
> roles of x and y are symmetrical, but I don't think it reasonable to
> expect the compiler to detect every situation in which distinct
> closed-over values give identically-behaved functions (in fact that's
> probably equivalent to the halting problem) so I'd consider it
> reasonable for it to consider closures unequal if they have distinct
> sequences of closed-over values (and I say "sequences" here because as
> fn-maker3 shows they aren't generally interchangeable; the constructor
> for fn-maker3's closure's class will have some particular order it
> takes them in and as sequences in that order they'd have to be equal
> for two fn-maker3 results to be treated as equal here).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to