clojure

julienvincent 2025-12-16T15:43:07.036339Z

I've been wanting a better way to define system interfaces at work and I came up with the start of an idea last night. I spent some time experimenting and produced this: https://github.com/julienvincent/malt. The basic idea is to allow defining a more concrete, typed interface from which implementations can be derived. I wanted to attach type information to the interface in a way that doesn't decay (like docs and comments) and that can participate at runtime to do things like coersion, validation, and generation. I'd love some feedback from people to see if this resonates with anyone, or if anyone knows of some prior work in this space. I know of plumatic schema supporting typed protocols but nothing beyond that. There is a note in the repo, but just to reiterate: I wouldn't recommend reading the source code. It was generated by AI. I defined the interface and desired behaviour, from which the macros and clj-kondo hooks were generated. I'll rewrite it myself if it proves to be a fruitful idea

lukasz 2025-12-16T15:45:08.375639Z

really neat, reminds me of how Prismatic Schema's extension of defrecord was done

julienvincent 2025-12-18T11:20:06.145319Z

Good point for defrecord, I expanded it to support defrecord as well!

👀 1
borkdude 2025-12-16T21:29:50.562499Z

:refer-clojure :exclude [def] is basically a no-op, right? https://github.com/clojure/spec.alpha/blob/eaae63904808a0988f6723d1e9e1ee7db6f07ee5/src/main/clojure/clojure/spec/alpha.clj#L17C3-L17C67

user=> (ns foo (:refer-clojure :exclude [def]))
nil
foo=> (def x 1)
#'foo/x
foo=> (ns bar)
nil
bar=> (defmacro def [])
#'bar/def
bar=> (def x 1)
#'bar/x

phronmophobic 2025-12-16T21:32:49.206799Z

There is no def in clojure.core.

> #'clojure.core/def
Unable to resolve var: clojure.core/def in this context

phronmophobic 2025-12-16T21:33:50.574399Z

def exists before clojure.core, https://github.com/clojure/clojure/blob/e43644847d03e6a27a28f99f1d7699da63f1069e/src/clj/clojure/core.clj#L13

dpsutton 2025-12-16T21:35:34.891599Z

this is just a consequence that special forms cannot be shadowed in first position? (invoke position?)

🎯 1
borkdude 2025-12-16T21:57:44.460259Z

I know all that, I just wonder why def is in :exclude

dpsutton 2025-12-16T21:58:33.333589Z

I think I did a thread on this a bit ago that that is unchecked. You can put anything in there

borkdude 2025-12-16T22:00:04.117219Z

yeah, you can put anything there, that's why I have an open clj-kondo issue to check of the var really exists. but since there is a special form in there, I wondered if there was any reason for it

bronsa 2025-12-17T10:05:55.937099Z

the only reason I can think of is for some linter warning about redefs (even if it's not true). maybe cursive would have complained at the time?

borkdude 2025-12-17T10:33:23.138249Z

maybe clj-kondo back in the day

2
borkdude 2025-12-17T10:39:13.074369Z

no, clj-kondo never complained about this (and spec was already written before it even existed)

2025-12-19T15:09:20.254679Z

til

2025-12-19T15:09:36.510579Z

:exclude being unchecked feels like a bug to me

borkdude 2025-12-19T15:10:58.529149Z

not sure if I would call it a bug, but at least it keeps me off the streets and something to add to clj-kondo, so I don't complain

1
2025-12-19T15:11:47.221079Z

My measly Clojurists Together monthly donation is going to good then 🙌🏻

1
2025-12-19T15:13:16.900059Z

@jeaye this is odd enough behavior that I'm tagging you for jank out of curiosity for how it handles this. Also makes me wonder if we should test stuff like this in clojure-test-suite as well

phronmophobic 2025-12-19T18:34:39.675079Z

It's important for :exclude to be unchecked so that you can write code that works on old and new versions of clojure:

(ns foo (:refer-clojure :exclude [;; added in 1.11
                                  update-vals]))

👍 1
jeaye 2025-12-19T18:36:45.093029Z

@emma.audrey.g jank's output from the same session inputs.

❯ jank repl
user=> (ns foo (:refer-clojure :exclude [def]))
nil

foo=> (def x 1)
#'foo/x

foo=> (ns bar)
nil

bar=> (defmacro def [])
#'bar/def

bar=> (def x 1)
#'bar/x
So, same behavior as Clojure, if I understand correctly.

👍 1
1