<< Back to previous view

[LOGIC-144] Extending cljs.core.logic with all of the functionality from clojure.core.logic Created: 19/Nov/13  Updated: 02/Jan/16

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Adrian Medina Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: None


Repo I've been working from is here: https://github.com/aamedina/cljs.core.logic

I've followed the code layout in clojure.core.logic pretty much verbatim, compensating for ClojureScript necessities, moved macros into sister .clj files. I have no hard opinions about the best way to organize the macros for each file, the way I do it is just the way I've found easiest, because then you don't have to namespace qualify every syntax quoted form that references a function in the sister .cljs file.

Additionally I ported all of the clojure.core.logic tests with clojurescript.test.

Comment by Adrian Medina [ 27/Nov/13 10:43 PM ]

So I've updated the repo to reflect a more faithful adherence to the existing cljs.core.logic code conventions and organization. I'd appreciate any insight into how to potentially optimize the code to run more on par with the JVM.

Comment by David Nolen [ 04/Dec/13 1:09 AM ]

What kinds of performance problems are you observing? Do you have a particular benchmark that you're running?

Comment by Adrian Medina [ 04/Dec/13 12:18 PM ]

Appendo and membero are particularly slow.

(dotimes [i ie5] (run* [q] (== q true))) takes around ~4500ms, which is about 10x slower than the JVM.

After profiling, I've discovered the problem - pretty standard recursion optimizations are necessary, it's re-walking (by reunifying) lvars recursively as the code is executed. E.g.,
for appendo, (run 5 [q] (fresh [x y] (appendo x y q))) will expand into something like..

((_0) (_0 . _1) (_0 _1 . _2) ... ))

and it's slow because every new list is actually re-walking every previously unified lvar again.

I'll have more time to investigate this over the weekend, but I think it might be as simple as not generating unique lvars by default, since then the identical? for unification check should catch any attempted walk.

Comment by Ryan Munro [ 02/Jan/16 3:58 PM ]

I've been using clojure.core.logic & cljs.core.logic, and have been stumbling with API differences. With the new reader conditionals, I think it would make sense to deprecate cljs.core.logic in favor of clojure.core.logic.

Does cljs.core.logic have specific implementations to make it performant on JS vms? Just looking at the code, it looks quite different, so these performance issues could also be caused by not as optimized algorithms.

I could help look into making clojure.core.logic portable, though I'm pretty new to clojure. My strategy would be adding reader conditionals until the test suite passes in clojurescript.

Generated at Mon Jan 23 15:24:41 CST 2017 using JIRA 4.4#649-r158309.