Welcome! Please see the About page for a little more info on how this works.

0 votes
in core.logic by

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.

5 Answers

0 votes
by

Comment made by: adrianm

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.

0 votes
by

Comment made by: dnolen

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

0 votes
by

Comment made by: adrianm

Appendo and membero are particularly slow.

(dotimes (link: i ie5) (run* (link: 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 (link: q) (fresh (link: 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.

0 votes
by

Comment made by: munro

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.

0 votes
by
Reference: https://clojure.atlassian.net/browse/LOGIC-144 (reported by adrianm)
...