Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

everyp/somef operational equality bug #6

Closed
frenchy64 opened this issue Sep 12, 2022 · 5 comments
Closed

everyp/somef operational equality bug #6

frenchy64 opened this issue Sep 12, 2022 · 5 comments

Comments

@frenchy64
Copy link
Owner

This line:

(every? #(and (p1 %) (p2 %) (p3 %)) args)

should be

(and (every? p1 args) (every? p2 args) (every? p3 args))

Basically the same problem as https://clojure.atlassian.net/browse/CLJ-2649 but in the rest arity.

@NoahTheDuke
Copy link

NoahTheDuke commented Sep 12, 2022

You think it should check all of p1 before checking all of p2, etc? My imperative intuition would loop over the arguments and check each predicate against them (as it works now).

@frenchy64
Copy link
Owner Author

Yes, I was surprised too. When I say "should", I'm referring to the operational equivalence with:

(defn everyp [& ps]
  (fn [& args] (every? #(every? % args) ps)))

I think the "imperative" version you're talking about of would be:

(defn everyp [& ps]
  (fn [& args] (every? (fn [x] (every? #(% x) ps) args)))

The problem is that the semantics are mixed. I think having both versions would be cool, but in different functions.

@frenchy64
Copy link
Owner Author

frenchy64 commented Sep 12, 2022

It's even worse than I thought. In these inner rest arities, ep3 checks x, y, z against p1, then p2 then p3, but then the every? starts all over again for the rest of the args, but in the opposite order.

       ([x y z & args] (boolean (and (ep3 x y z)
                                     (every? #(and (p1 %) (p2 %) (p3 %)) args))))))

ie., this is the checking order:

(p1 x) (p1 y) (p1 z)
(p2 x) (p2 y) (p2 z)
(p3 x) (p3 y) (p3 z)
(p1 args0)
(p2 args0)
(p3 args0)
(p1 args1)
(p2 args1)
(p3 args1)
...

@frenchy64
Copy link
Owner Author

frenchy64 commented Sep 12, 2022

I think it should be:

       ([x y z & args] (boolean (and (p1 x) (p1 y) (p1 z) (every? p1 args)
                                     (p2 x) (p2 y) (p2 z) (every? p2 args)
                                     (p3 x) (p3 y) (p3 z) (every? p3 args))))))

Smaller:

       ([x y z & args] 
        (let [test #(and (% x) (% y) (% z) (every? % args))]
          (boolean (and (test p1) (test p2) (test p3)))))

@frenchy64 frenchy64 changed the title everyp operational equality bug everyp/somef operational equality bug Sep 20, 2022
@frenchy64
Copy link
Owner Author

Same problem with somef. The arities that recur via sf2, sf3, sfn flip the order.

frenchy64 added a commit that referenced this issue Sep 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants