beginners 2026-06-11

Good morning! I have a new book that has a chapter on clojure.core.logic, and I want to play with it. I've never done logic programming, but it looks really neat. I've hit an example in the book though that I'm trying to run and I'm getting an error.

(run* [q]
   (fresh [x y z a]
       (== q [x y z])
       (fd/in x y z a (fd/interval 1 100))
       (fd/distinct [x y z])
       (fd/< x y)
       (fd/< y z)
       (fd/+ x y a)
       (fd/+ a z 100)))
The error is: > Error printing return value (ClassCastException) at clojure.lang.Numbers/equiv (Numbers.java:240). > class clojure.core.logic.LVar cannot be cast to class java.lang.Number (clojure.core.logic.LVar is in unnamed module of loader clojure.lang.DynamicClassLoader @142ea233; java.lang.Number is in module java.base of loader 'bootstrap') I think it's not liking:
(== q [x y z])
What am I doing wrong here ?

Oh wait! Hold on. I think I've missed somethign that I typed into the repl earlier, when i was going through the examples by typing straight into the repl. I Need to refer ==

Yep, sorry, I had to make my namespace bit be

(ns logical.core
  (:require [clojure.core.logic.fd :as fd]
            [clojure.core.logic :refer [run run* fresh ==]]))
Now it works!

It's a good practice to add (:refer-clojure :exclude [==]) to your ns form as well, to be explicit about the 'shadowing' of the core var

👍 1

that's probably clj-kondo not understanding the fresh macro and giving a unresolved-symbol false positive, you can add a config to have it be recognized but I'd just ignore it for now~

I have this in my .clj-kondo/config.edn:

{:lint-as       {clojure.core.logic/fresh clojure.core/fn
                 clojure.core.logic/run* clojure.core/fn}}

👍 2

thats a neat trick! I was thinking more along the lines of

{:config-in-call {clojure.core.logic/fresh {:ignore [:unresolved-symbol]}}}
which is more of a mouthful